Reputation: 7173
In Objective-C, it was really easy and nice to be able to do
- (UIButton *)backButton{
if(!_backButton){
_backButton = [UIButton new];
}
}
In Swift however, when you override a property getter, it's called a computed variable and every time self.backButton
is accessed, the variable is recomputed. The following example illustrates this nicely:
private var backButton: UIBarButtonItem {
let button = UIButton(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width*0.06, height: self.view.frame.size.width*0.06))
button.setImage(UIImage(named: "back_arrow"), forState: UIControlState.Normal)
button.rac_signalForControlEvents(UIControlEvents.TouchUpInside).subscribeNext {
(next: AnyObject!) -> () in
self.navigationController?.popViewControllerAnimated(true)
return ()
}
println("Recalculating the button")
let item = UIBarButtonItem(customView: button)
return item
}
The println statement is called every time I access self.backButton. Addtionally, the memory address printed out also changes every time. I understand that that's the nature of computed variables since they are not stored in memory.
Is this an analogous way to replicate the exact same behavior seen in Obj-C in Swift? All I want is a way to instantiate some UI variable once without having to put that code in the initialization method.
Upvotes: 1
Views: 1461
Reputation: 4520
What you are referring to is called "lazy instantiation".
You can reproduce it in swift using the lazy
keyword:
private lazy var backButton: UIBarButtonItem = {
let button = .....
//....
return button
} ()
Upvotes: 2
Reputation: 41236
The best way is to probably create it as a lazy variable, that way the initializer will be called one time, the first time it's accessed.
lazy var backButton:UIBarButtonItem = {
let button = ...
return button
} ()
By using an initializer block, you can provide complex initialization of the instance variable.
Upvotes: 4