Swift Lazy 属性 初始化循环引用编译错误?
Swift Lazy Property Initialization Circular Reference Compilation Error?
谁能解释一下为什么下面的代码在编译时会出现循环引用错误?
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()
}
}
但是,如果我将其更改为:
class Bar {
lazy var foo: Foo = {
return Foo { [weak self] in
self?.foo.someFunc()
}
}()
}
那么就没有循环引用错误了
我很困惑为什么一个会导致错误,而另一个不会。
已更新:
循环引用在类型推断中:就是foo
的类型依赖于self.foo
的类型,而self.foo
的类型又依赖于foo
的类型,这取决于 self.foo
的类型等。
上一个答案:
我想我找到了根本原因(感谢我的一些同事!):
我的同事注意到这段代码编译得很好,这指出它可能是类型推断问题。我被包装闭包弄糊涂了,这显然与真正的问题无关。
class Bar {
lazy var foo: Foo = Foo { [weak self] in
self?.foo.someFunc()
}
}
我认为为了让编译器评估 Bar
它必须对 属性 foo
进行类型推断,这需要编译器评估 属性初始化代码。但是 属性 初始化代码本身包含对 self
/Bar
的引用,因此为了评估该代码,必须首先评估 Bar
。因此循环引用。
问题在这里:
lazy var foo = Foo { [weak self] in
self.foo.someFunc()
} // ^^^
所以您是根据 foo
定义 foo
。那是一个圆圈。和说
没什么区别
lazy var foo = self.foo
这是很明显的圆形。
当您将整个事物包装在一个评估级别({...}()
构造)时,对 self.foo
的内部引用保证不会被评估,直到稍后。
谁能解释一下为什么下面的代码在编译时会出现循环引用错误?
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()
}
}
但是,如果我将其更改为:
class Bar {
lazy var foo: Foo = {
return Foo { [weak self] in
self?.foo.someFunc()
}
}()
}
那么就没有循环引用错误了
我很困惑为什么一个会导致错误,而另一个不会。
已更新:
循环引用在类型推断中:就是foo
的类型依赖于self.foo
的类型,而self.foo
的类型又依赖于foo
的类型,这取决于 self.foo
的类型等。
上一个答案:
我想我找到了根本原因(感谢我的一些同事!):
我的同事注意到这段代码编译得很好,这指出它可能是类型推断问题。我被包装闭包弄糊涂了,这显然与真正的问题无关。
class Bar {
lazy var foo: Foo = Foo { [weak self] in
self?.foo.someFunc()
}
}
我认为为了让编译器评估 Bar
它必须对 属性 foo
进行类型推断,这需要编译器评估 属性初始化代码。但是 属性 初始化代码本身包含对 self
/Bar
的引用,因此为了评估该代码,必须首先评估 Bar
。因此循环引用。
问题在这里:
lazy var foo = Foo { [weak self] in
self.foo.someFunc()
} // ^^^
所以您是根据 foo
定义 foo
。那是一个圆圈。和说
lazy var foo = self.foo
这是很明显的圆形。
当您将整个事物包装在一个评估级别({...}()
构造)时,对 self.foo
的内部引用保证不会被评估,直到稍后。