5

I am trying to understand how lazy works in swift. The following code compiles without any error.

import UIKit
class Test : UIViewController{
    let i = 1
    lazy var j:Int =  self.i
}

Whereas if I remove the type of j and make it inferred like the code below,

import UIKit
class Test : UIViewController{
    let i = 1
    lazy var j =  self.i
}

I get compilation error "Value of type 'NSObject -> () -> Test' has no member 'i'"

Can someone explain what is going on with the compiler. Thanks

2 Answers 2

4

You need to consider 3 aspects here.

  • A lazy stored property is a property whose initial value is not calculated until the first time it is used. That is when you call the property for the first time its value will be calculated.
  • As the actual value is created by evaluation, you need to declare lazy variable's data type up front.
  • The properties you declare in your class are the instance variables, if you need to access their values you need an instance(object) of the class.

Let us consider following line from your non working code

lazy var j =  self.i

Two problems are present in your non working code. First is you have not specified the data type of your lazy var. As the declaration is incomplete compiler won't treat 'j' as lazy var it will treat is as normal instance variable. You must be aware about swift's rule that whenever you declare any variable in the class you must assign some value to it or else you can make that variable optional. In above statement you are trying to assign i's value to j by using self within the class. When compiler is compiling that line no object of the class is created and the self you are using is nil that is why compiler is throwing the error(It will throw error even if you don't use self due to the same reason mentioned above).

Why it is not causing problems in your working code:

lazy var j:Int =  self.i

As I have mentioned above the value to lazy var is assigned when you call that variable. How will you call that variable out side the class? Of course by creating object. And when you will call it with the help of object 'self' will point to the same object and self won't be nil it won't cause any problem.

In short two things you need to understand 3 things

  • While declaring lazy var you have to specify the data type
  • lazy var is not assigned when it is declared, it is assigned when it is called
  • you can not call instance var without instance(object) of your class
Sign up to request clarification or add additional context in comments.

2 Comments

I don't think data type is needed when declaring the lazy var. The code lazy var name = "some name" compiles without any problem
If you are passing any hardcoded value to lazy var it doesn't require data type compiler will understand the type that is why lazy var name = "some name" is working. In your code you are not assigning value directly you are trying to assign i's value with help of self. Here compiler is unaware of self,i and i's data type. That is why data type is require in such cases as well as in the case where you are writing closure of you lazy var.
0

Here is an example of lazy initialization with a view controller

Note the () at the end

lazy var myViewController : MyViewController? = {
    let storyboard: UIStoryboard = UIStoryboard(name: "MyVC", bundle: nil)
    return storyboard.instantiateViewController(withIdentifier: "MyAccount") as? MyViewController
}()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.