Caputure属性价值导致通过_property风格保持循环



我有一个类,有一个适当的块:

@property(nonatomic, strong) void (^hehe)();

在 init 方法中,我执行以下工作:

__weak test *weakSelf = self;
self.hehe = ^{
test *self = weakSelf;
NSLog(@"%zd", self.a);
NSLog(@"%zd", self->_a);
NSLog(@"%zd", _a);
};

块中的最后两行有什么区别。

我以为self->_a等于_a.

但是Xcode在最后一行显示警告:

Caputuring self strongly in this block is likely to lead a retain cycle


编辑:

我知道本地自我和全球自我是不一样的。操作系统如何区分差异。我使用 clang 重写了代码,并得到以下内容:

static void __ViewController__init_block_func_0(struct __ViewController__init_block_impl_0 *__cself) {
__Block_byref_weakSelf_0 *weakSelf = __cself->weakSelf; // bound by ref
ViewController *self = (weakSelf->__forwarding->weakSelf);
NSLog((NSString *)&__NSConstantStringImpl__var_folders_gp_6ztdfl3n5919c3y4pb03gd340000gn_T_ViewController_ad5b98_mi_0, ((NSInteger (*)(id, SEL))(void *)objc_msgSend)((id)self, sel_registerName("a")));
NSLog((NSString *)&__NSConstantStringImpl__var_folders_gp_6ztdfl3n5919c3y4pb03gd340000gn_T_ViewController_ad5b98_mi_1, (*(NSInteger *)((char *)self + OBJC_IVAR_$_ViewController$_a)));
NSLog((NSString *)&__NSConstantStringImpl__var_folders_gp_6ztdfl3n5919c3y4pb03gd340000gn_T_ViewController_ad5b98_mi_2, (*(NSInteger *)((char *)self + OBJC_IVAR_$_ViewController$_a)));
}

最后两行使用相同的自我...

因为它意味着不同的self。快速重命名将使一切变得清晰:

__weak test *weakSelf = self;
self.hehe = ^{
test *strongSelf = weakSelf;
NSLog(@"%zd", strongSelf.a);
NSLog(@"%zd", strongSelf->_a);
NSLog(@"%zd", _a);
};

现在很明显,最后一行从块外捕获self。您命名它的方式使得区分作为块内声明的局部变量的self和从其范围之外捕获的self变得更加困难。

引用_a是对封闭作用域中实例变量的直接引用。这隐含地捕捉了自我。它不会调用属性的 getter/setter。它直接指向实例变量。

不要从持续存在的块内部执行此操作。(苹果已经开始称之为"转义"块。使用弱自我/强自我语法@Losiowaty在他的答案中显示。

相关内容

最新更新