Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lazy loading Properties in swift

Tags:

swift

I'm attempting to wrap my head around the Swift language. A common pattern when building views in code with Objective-C is to override UI properties and lazy load them like so:

@property(nonatomic, strong) UILabel *myLabel;  - (UILabel *)myLabel {      if (!_myLabel) {          _myLabel = [[UILabel alloc] initWithFrame:CGRectMake(20.0f, 75.0f, 320.0f, 20.0f)];         [_myLabel setFont:[UIFont subHeadlineFont]];         [_myLabel setTextColor:[UIColor subHeadlineColor]];         [_myLabel setText:@"Hello World"];      }      return _myLabel; }  - (void)viewDidLoad {     [super viewDidLoad];     [self.view addSubview:self.myLabel]; } 

This allows for the configuration of UIElements to be self contained within their setup but doesn't result in reconfiguring them every time.

It seems we don't have access to the backing store in Swift and the @lazy keyword doesn't really have the same semantics.

I'm curious if anyone has identified a similar pattern in Swift that allows one to keep the configuration of variables and constants together with their declaration in a neat syntactic way that doesn't result in reconfiguration every time?

like image 681
Brent Westmoreland Avatar asked Jun 05 '14 19:06

Brent Westmoreland


People also ask

What is the lazy property in Swift?

A lazy stored property is a property whose initial value isn't calculated until the first time it's used. You indicate a lazy stored property by writing the lazy modifier before its declaration.

What is lazy loading in Swift?

Lazy loading is a design pattern commonly used in computer programming to defer initialization of an object until the point at which it is needed. It can contribute to efficiency in the program's operation if properly and appropriately used. The opposite of lazy loading is eager loading.

Why we use lazy property in Swift?

Lazy variables allow you to delay the initialisation of stored properties. This can be useful to only perform expensive work when it's actually needed. The different between lazy- and computed properties is important in cases you need to have calculations based on the current state of values.

What is lazy and weak in Swift?

The error message is completely useless at explaining what is going on, but essentially lazy and weak are at odds with each other: lazy tells Swift that you don't want your variable created until the first time you access it, but once it is created, you want to keep it indefinitely for future reference, while.


2 Answers

I think a lazy property initialized with a closure would work:

lazy var myLabel: UILabel = {     var temporaryLabel: UILabel = UILabel()     ...     return temporaryLabel }() 

As I read “The Swift Programming Language.” (Checkerboard example) the closure is only evaluated once).

like image 144
Christian Otkjær Avatar answered Sep 22 '22 17:09

Christian Otkjær


class Thingy {     init(){         println("making a new Thingy")     } }  var thingy = {     Thingy(); }()  println("\(self.thingy)") println("\(self.thingy)") 

The log message "making a new Thingy" appears just once, proving that only one Thingy was created - the closure was called only once, namely to initialize this property. This is effectively what you are describing. All you have to do is add more to the closure so as to configure it the returned object.

If you make the var @lazy and comment out the println statements, no Thingy is created, proving that the laziness does what it is intended to do; you could omit this, however, since you know that the label will in fact always be needed early on. The point of @lazy is to prevent the closure from ever being called unless the getter is called, but you are always going to call the getter so that is pointless in your situation.

like image 27
matt Avatar answered Sep 20 '22 17:09

matt