Lazy Variable with Closure

lazy variable with closure

The tutorial code you quote is this:

private lazy var variable:SomeClass = {
let fVariable = SomeClass()
fVariable.value = 10
return fVariable
}()

Contrast it with this:

private var variable:SomeClass {
let fVariable = SomeClass()
fVariable.value = 10
return fVariable
}

The first one initializes variable to a newly created SomeClass instance, once at most (and maybe not even that many times). The second one is a read-only computed variable and creates a new SomeClass instance every time its value is read.

Difference between Lazy var and var as-a-closure in Swift

The difference is when the init code for the variable is run. For lazy vars, the init code is run on first access of that variable. For non-lazy vars, it's run when the struct/class is initialized.

struct N {
lazy var a: Int = { print("Setting A"); return 5}();
var b: Int = { print("Setting B"); return 5 }()
}

var n = N()
print(n.a)
print(n.b)

Output:

Setting B
Setting A
5
5

Note how non-lazy b is initialized first. a is only initialized when it's accessed. In either case, the initializer for each property is only run once.

Swift: Not initialised Lazy Variable that returns Closure

You don't need two return statements in a row nor do you need a lazy closure. Why not just do:

let time: () -> String = {
return String(describing: Date())
}

Or just replace this whole thing with a method:

func time() -> String {
return String(describing: Date())
}

One reason why you might want to use a closure here is that you want other parts of your code to change the value of the closure. If that's the case, just do it like the first snippet, otherwise I don't think anything is preventing you from writing a method. You can pass a method around just like a closure, because methods are a kind of closure!

Lazy variables are really needed when initializing them takes much resources. Creating closures tend to be cheap.

Setting a variable to a defined lazy var within a UIView closure cause reference problems

You were intended to use computed property of swift. But didn’t get it right. Your profile label should have been defined as follows.

var profileLabel: UILabel {
get {
let label = UILabel()
label.font = .displayNameLabel
label.textColor = .profileLabel
label.numberOfLines = .numberOfLines
label.textAlignment = .center
label.translatesAutoresizingMaskIntoConstraints = false
return label
}
}

Swift must use lazy for stored property when use self in closure?

When you are declaring label with lazy initial value is not calculated until the first time it is used.
so the probably the Instantiates views was completed.

But the concept of using let in Swift, variables which are let have to be initialized before you can use self.

Using lazy var means that the compiler can verify that the value assigned to label won't be accessed before self is a valid object, because it won't be possible to call label until all other members of the class have been initialized.

Swift lazy var reference cycle

The reason that there isn't is a reference cycle is because the closure isn't stored on a. If a stored the closure and the closure contained self then there would be a reference cycle.

For lazy properties, everything after the = isn't called until the first time you access property2. When you do, the closure is created, called, freed from memory, and then the value is returned to you. This is why you can get rid of the self. in the closure since it will never capture self.

Swift Lazy Property Initialization Circular Reference Compilation Error?

Updated:

The circular reference is in the type inferencing: It's the fact that foo's type depends on self.foo's type, which depends on foo's type, which depends on self.foo's type etc..

Previous Answer:

I think I figured out the root cause here (Thanks to some of my coworkers!):

My coworker noticed that this code compiles fine, which points out it might be a type inference issue. I was being thrown off by the wrapping closure, which apparently has nothing to do with the real issue.

class Bar {

lazy var foo: Foo = Foo { [weak self] in
self?.foo.someFunc()
}
}

I think the in order for the compiler to evaluate Bar it must do type inference on the property foo, which requires the compiler to evaluate the property initialization code. However the property initialization code itself contains a reference to self/Bar, so in order for that code to be evaluated, Bar must be evaluated first. And thus the circular reference.



Related Topics



Leave a reply



Submit