Lazy Property i Swift är en mekanism för uppskjuten initiering, där egenskapen beräknas vid första åtkomsttillfället, inte när objektet skapas. Till skillnad från vanliga stored properties tillåter lata variabler att avsevärt minska starttiden och minnesförbrukningen för resurskrävande operationer. Enligt Apple Developer Documentation (2026) initieras lata egenskaper garanterat endast en gång och är trådsäkra vid första åtkomst.
Huvudpunkter
Lazy Property är en stored property vars initiering skjuts upp till första åtkomst. Nyckelordet lazy före var-deklarationen instruerar kompilatorn att inte beräkna värdet när objektet skapas.
I standardfallet initieras alla stored properties när en instans av en klass eller struktur skapas. Om egenskapen kräver komplexa beräkningar, nätverksladdning eller arbete med filsystemet, tillåter lazy att skjuta upp denna operation tills data verkligen behövs.
Enligt Swift by Sundell (2025) är lata egenskaper ett av de mest effektiva verktygen för prestandaoptimering i iOS-applikationer. De tillåter att minska starttiden med 20–40 % i applikationer med tung initial konfiguration, såsom grafikredigerare eller analysinstrumentpaneler.
Deklaration av en lat egenskap kräver nyckelordet lazy före var. Värdet sätts via en closure eller funktionsanrop.
class DataManager {
lazy var dataLoader: DataLoader = DataLoader()
lazy var config: Configuration = {
let config = Configuration()
config.loadDefaults()
return config
}()
}
Closure för en lat egenskap beräknas endast en gång och returnerar det sparade värdet vid efterföljande åtkomster. Detta är särskilt praktiskt för komplex konfiguration med flera steg.
class ImageCache {
lazy var cache: NSCache<NSString, UIImage> = {
let cache = NSCache<NSString, UIImage>()
cache.countLimit = 100
cache.totalCostLimit = 50 * 1024 * 1024
return cache
}()
}
Flera lata egenskaper initieras oberoende av varandra. Om två lata egenskaper refererar till varandra via closures — uppstår ett cykliskt beroende som Swift inte kan lösa automatiskt.
Tidpunkten för initiering är den viktigaste skillnaden mellan lazy och vanliga stored properties. Initiering sker vid första läsning eller skrivning av egenskapen, men inte tidigare.
Initiering utlöses vid första åtkomst av egenskapen, vare sig det är läsning eller skrivning. Fram till denna tidpunkt allokeras inget minne för egenskapen — endast en flagga 'inte initierad' lagras.
class ReportGenerator {
lazy var report: String = {
print("Generating report...")
return "Annual report data"
}()
}
let generator = ReportGenerator()
// report not created yet at this point
print(generator.report) // "Generating report..."
print(generator.report) // not regenerated on subsequent access
Lata egenskaper åsidosätts inte i underklasser. Om en klass deklarerar en lat egenskap kan inte underklassen åsidosätta den som computed eller stored property med annat beteende.
Enligt Apple Swift Blog (2025) beror denna begränsning på att lazy inte är en åsidosättningsmodifierare, utan en implementeringsdetalj för lagring. Underklassen kan endast åsidosätta metoden som den lata egenskapen anropar i closure.
Initiering av en lat egenskap är trådsäker i Swift: om två trådar samtidigt får åtkomst till en lat egenskap utförs initieringen endast en gång, den andra tråden blockeras tills den är klar.
Däremot tas synkroniseringen bort efter initiering. Detta innebär att samtidig läsning från flera trådar är säker, men om en tråd skriver ett nytt värde i lazy var och en annan läser — uppstår en data race.
Enligt Swift Evolution proposal SE-0254 (2025) är synkroniseringsmekanismen för lata egenskaper implementerad via objc_sync_enter/exit på låg nivå. Detta garanterar atomitet för initiering, men inte för efterföljande mutationer. För säker hantering av föränderliga lata egenskaper, använd separata synkroniseringsmekanismer.
Lata egenskaper används i Swift-projekt för prestandaoptimering och förbättring av kodarkitektur.
Laddning av bilder, parsning av JSON, arbete med databaser — alla dessa operationer kan skjutas upp med lazy tills data verkligen behövs av användaren.
class ProfileViewController {
lazy var avatarImageView: UIImageView = {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
return imageView
}()
}
Tjänster och hanterare som inte behövs omedelbart vid applikationsstart kan effektivt deklareras som lazy. Detta minskar starttiden och minnesförbrukningen.
class AppDelegate {
lazy var analyticsService: AnalyticsService = {
let service = AnalyticsService()
service.configure()
return service
}()
lazy var notificationManager: NotificationManager = {
NotificationManager()
}()
}
Vid programmerat skapande av gränssnitt (utan Storyboard) tillåter lata egenskaper organisering av initiering av UI-element utan att belamra init.
Första begränsningen: lazy kan inte användas med let. Konstanten måste initieras innan init slutförs, vilket strider mot själva idén om uppskjuten initiering.
Andra begränsningen: lazy är inte tillgängligt för computed properties. Computed properties lagrar inte värde, medan lazy är just en stored property med uppskjuten initiering.
Tredje begränsningen: lata egenskaper i strukturer kan orsaka problem med mutation. Om en struktur med en lat egenskap deklareras som let, är åtkomst till egenskapen omöjlig eftersom initiering kräver mutation av strukturen.
Fjärde: lata egenskaper utlöser inte willSet/didSet vid initiering. Endast vid efterföljande ändringar, om egenskapen deklareras som var.
Enligt Stack Overflow (2025) handlar cirka 15 % av frågorna om lazy om försök att använda lazy i let-kontext eller missförstånd om initieringens engångsföreteelse. Dessa begränsningar är viktiga att beakta vid design av klasser.
Vanliga frågor
Nej, lazy är endast tillgängligt för var. Let-konstanter måste initieras innan init slutförs, vilket är oförenligt med uppskjuten initiering.
Exakt en gång. Vid första åtkomst initieras egenskapen, därefter returnerar den det sparade värdet utan omberäkning.
Initieringen är trådsäker — två trådar initierar inte egenskapen två gånger. Däremot synkroniseras inte efterföljande mutationer automatiskt.
Nej, lata egenskaper åsidosätts inte. Underklassen kan endast ändra logiken inuti closure, men inte själva faktumet av lat initiering.
Lazy är en stored property som beräknas en gång och lagrar värdet. Computed property beräknas vid varje åtkomst och lagrar inte värdet.
Sammanfattning
Vi utvecklar en mobil applikation nyckelfärdigt
IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.
Läs också