Swift闭包弱引用捕获返回nil?预期不符问题咨询
问题原因解析
核心问题在于:闭包用[weak foo]捕获时,外部的foo变量还没完成赋值,捕获到的是nil
执行顺序拆解
- 执行
foo = MyClass { [weak foo] in ... }这行代码时,会先执行右侧的MyClass初始化逻辑,此时闭包被创建。 - 闭包创建的瞬间,外部的
foo变量还没有被赋值为刚创建的MyClass实例(赋值动作要等MyClass初始化完成后才会执行),所以此时foo的取值是nil。 [weak foo]捕获的是当前foo指向的对象的弱引用,也就是nil。后续foo被赋值为实例后,闭包里的弱引用不会自动更新,因此调用fnc()时输出的是nil。
无弱引用时正常的原因
当不使用弱引用时,闭包捕获的是foo变量本身(而非变量当时指向的对象),相当于闭包里的foo和外部的foo共享同一个存储单元。当foo被赋值为实例后,闭包里访问的就是这个变量的最新值,因此能正确输出Optional(1)。
正确写法
如果要避免循环引用同时正确访问实例属性,应该捕获self(因为闭包是MyClass实例的属性,self就是当前正在创建的实例):
var foo: MyClass? foo = MyClass { [weak self] in print("Foo: \(self?.int)") } foo?.fnc()
此时闭包捕获的是当前MyClass实例的弱引用,初始化时self已经指向正在创建的实例,调用fnc()时能正确访问到int属性,输出Foo: Optional(1)。
内容的提问来源于stack exchange,提问作者user1670679
相关产品推荐
相关产品推荐

