Lazy initialization (also sometimes called lazy instantiation, or lazy loading) is a technique for delaying the creation O F an object or some other expensive process until it ' s needed. When programming-IOS, this is helpful-to-make sure you utilize only the memory of your need when you need it.
This technique are so helpful, in fact, which Swift added direct support for it with the lazy
attribute.
To understand what this is useful, let's first go over the old by creating lazy properties.
The old
In Objective-c, if you had a mutable an array property of you wanted lazily initialized, you ' d has to write this:
@property (nonatomicstrong< Span class= "P" >) nsmutablearray *players; - (nsmutablearray *) players {if (! _players) {_players = [[ nsmutablearray allocinit} return _players;}
To people new-objective-c, this presents a few different learning curves. First of all, you need to know that the method name have to exactly match the property name. If you misspelled the method name, this would silently fail and players
would is nil when you tried to access it.
You also need to know the _players
instance variable is created for your automatically when your property is synthesized. Before Xcode 4.4, you had to manually synthesize your variable using @synthesize
the keyword, like so:
@synthesize players;// - or -@synthesize players = _players;
Which would tell you the instance variable used for the Players property is _players
. Nowadays Xcode handles synthesizing your properties for you. If you didn ' t know that and then using the underscore before the property name might is not immediately obvious.
The Swift
Now in Swift, the can all is simplified down to the one line:
lazy var players = [String]()
Simple, concise, and straight to the point.
Keep in mind do need to declare your lazy property using var
the keyword, not the let
keyword, because constants Mu St always has a value before initialization completes.
If you wanted to add logic to your lazy initialization, Swift makes this easy by letting you define a closure after your L Azy Property:
lazy var players: [String] = { var temporaryPlayers = [String]() temporaryPlayers.append("John Doe") return temporaryPlayers }()
If you prefer, you can also lazily initiate your property using a instance method:
lazy var players: [String] = self.initialPlayers() func initialPlayers() -> [String] { var players = ["John Doe"] return players}
Or A class method:
class testclass { lazy var players = testclass< Span class= "O". initialplayers () class func () -> [string {var players = [ "John Doe" return players } }
But people would most likely prefer using the new closure mechanic, as it keeps the logic near the property declaration.
When is should I use lazy initialization?
One example of when-to-use-lazy initialization is-when-the-initial value for-a property isn't known until after the OBJEC T is initialized.
For example, if you had a person class and a property personalizedGreeting
. The property personalizedGreeting
can, lazily instantiated after the object are created so it can contain the name of the person. Here's a quick example:
ClassPerson{VarName:string lazy var personalizedgreeting : string = {[ unowned self] in return "Hello," span class= "se" >\ (self. Name) ! " } () init (name: string) {self. Name = name }}
(Note that we had to say this to [unowned self] in
prevent a strong reference cycle)
When you initialize a person, their personal greeting hasn ' t been created yet:
let person = Person(name: "John Doe")// person.personalizedGreeting is nil
But if you attempt-to-print out the personalized greeting, it's calculated on-the-fly:
NSLog(person.personalizedGreeting)// personalizedGreeting is calculated when used// and now contains the value "Hello, John Doe!"
Another good time-to-use lazy initialization was when the initial value of a property is computationally intensive.
For example, if you had an object that performs some really intense algorithm to determine the number of faces in a pictu Re, make the property numberOfFaces
lazily initialized.
Or If you had a class this calculates several different large numbers, you would want to make sure they ' re only calculated On-demand:
class MathHelper { lazy var pi: Double = { // Calculate pi to a crazy number of digits return resultOfCalculation }()}
Conclusion
Direct support for lazy property initialization is just one of the many great features of Swift. In the next few months, I'll cover more great features and shortcuts. Stay tuned!
Updated 7/23/14:updated to reflect the @lazy
attribute being changed to lazy
. Also updated to the new Array declaration syntax.
http://mikebuss.com/2014/06/22/lazy-initialization-swift/
Lazy initialization with Swift