40

What is the advantage or difference of initializing:

lazy var hintView: HintView = {
        let hintView = HintView()
        return hintView
}()

Instead of simply use:

var hintView = HintView()

(HintView is: class HintView: UIView {})

Help is very appreciated.

Rajan Maheshwari
  • 14,465
  • 6
  • 64
  • 98
David Seek
  • 16,783
  • 19
  • 105
  • 136
  • 2
    Given that `hintView` is a member of some type of which an instance will be instantiated sooner or later (say instance `foo`); the latter will always instantiate a `HintView` instance (as a member property) of `foo`, whereas the former will only instantiate a `HintView` instance in case `foo.hintView` is accessed. In case the instantiation of a `HintView` is equivalent to some computationally heavy load, it might be appropriate to only perform this instantiation in case the property it will be tied to is actually used. – dfrib Nov 19 '16 at 15:40
  • @dfri thank you very much for detailed description. since this is perfectly answering my question, please feel free to poste is as answer – David Seek Nov 19 '16 at 15:44
  • 2
    I believe the existing answers also cover this quite well, so I'll just leave it as the comment above. Happy to help! Might be worth pointing out one additional thing though (that I don't see below): `static` properties are `lazy` by default (mutable as well as immutable ones). – dfrib Nov 19 '16 at 15:48
  • Lazy var gets executed only once and the initial value will not get changed every time you try to access the value. – ranjit.x.singh Jun 27 '19 at 06:07

5 Answers5

91

Let's do it practically. See the screenshot

enter image description here

I just stopped the debugger in viewDidLoad. You can see that secondHintView has a memory as it was not lazy for the storage but hintView is still nil as it is a lazy one. The memory gets allocated once you use/access the lazy variables.

Also lazy should be var always.

Rajan Maheshwari
  • 14,465
  • 6
  • 64
  • 98
  • 1
    Can you please say an example where should we use lazy var. – Anees Feb 26 '20 at 05:49
  • 2
    @Anees you can use lazy in a variable waiting for response. `lazy var response` since the response is not there till you call your service. You can use lazy if you want to show customAlert on your vc but that is not always added on your VC. It will add from some condition. `lazy var alertView` etc. – Rajan Maheshwari Mar 24 '20 at 20:30
46

Lazy Stored Property vs Stored Property

There are a few advantages in having a lazy property instead of a stored property.

  1. The closure associated to the lazy property is executed only if you read that property. So if for some reason that property is not used (maybe because of some decision of the user) you avoid unnecessary allocation and computation.
  2. You can populate a lazy property with the value of a stored property.
  3. You can use self inside the closure of a lazy property
Luca Angeletti
  • 58,465
  • 13
  • 121
  • 148
10

A lazy stored property is calculated only when it is accessed for the first time.

It is var and not let because, the value is not initialized during the initialization process. It is calculated later on. That's why a lazy stored property need to be a variable and not a constant.

lazy var hintView: HintView = {
        let hintView = HintView()
        return hintView
}()

let h = hintView

In the above code, whenever, hintView is accessed for the first time, the closure assigned to it is executed and the value is returned and stored in h.

For more info refer to:

Swift lazy stored property versus regular stored property when using closure

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html

Community
  • 1
  • 1
PGDev
  • 23,751
  • 6
  • 34
  • 88
2

In certain cases, using lazy vars can be faster, because they are only calculated once, when you are accessing them for the first time.

Graham
  • 7,431
  • 18
  • 59
  • 84
FelixSFD
  • 6,052
  • 10
  • 43
  • 117
  • 7
    A stored let property is also calculated once, whats your point? – J. Doe Mar 02 '19 at 14:36
  • I guess he was trying to compare with get on computed variables – brenoxp Aug 14 '19 at 20:05
  • @J.Doe The point is that let is calculated immediately once, while lazy is calculated only when requested - meaning if you never try to access lazy variable it won't be ever calculated. This can be useful when variable computation is a bit more complex then some simple initialization – zhuber Feb 18 '21 at 10:33
2

It's a also a good practice to separate the contents/calculations of the variable in a separate function for readability like so:

// MARK: Public views
lazy var titleView = getTitleView()
lazy var hintView = getHintView(.red)
lazy var secondHintView = getHintView(.blue)
lazy var thirdHintView = getHintView(.yellow)
lazy var fourthHintView = getHintView(.brown)

// MARK: Private functions
private func getTitleView() -> TitleView {
   let view = TitleView()
   return view
}

private func getHintView(_ textColor: UIColor) -> HintView {
   let view = HintView()
   view.textColor = textColor
   return view
}

That way you can reuse some of the functionality, have to write less code and all of your variables are a lot more readable. E.g. I have 5 separate variables, but I can see them all with one glance.

KLD
  • 162
  • 2
  • 10