Can anyone explain why the following code will result in a circular reference error while compiling?
class Foo {
let closure: ()->()
func someFunc() {}
init(closure: @escaping ()->()) {
self.closure = closure
}
}
class Bar {
lazy var foo = Foo { [weak self] in // Circular Reference error here!
self?.foo.someFunc()
}
}
However if I change it to:
class Bar {
lazy var foo: Foo = {
return Foo { [weak self] in
self?.foo.someFunc()
}
}()
}
then there is no circular reference error anymore.
I'm confused why one would cause an error, and the other would not.
The issue is here:
lazy var foo = Foo { [weak self] in
self.foo.someFunc()
} // ^^^
So you are defining foo
in terms of foo
. That's a circle. It's no different from saying
lazy var foo = self.foo
which is very obviously circular.
When you wrap the whole thing in a level of evaluation (the {...}()
construct), the inner reference to self.foo
is guaranteed not to be evaluated until later.
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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.