我有一个班级,有一个块:
@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
编辑:
我知道当地的自我和全球的自我是不一样的。 os如何区分差异。我使用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)));
}
最后两行使用相同的自我......
答案 0 :(得分:1)
因为它意味着不同的self
。快速重命名将使一切清晰:
__weak test *weakSelf = self;
self.hehe = ^{
test *strongSelf = weakSelf;
NSLog(@"%zd", strongSelf.a);
NSLog(@"%zd", strongSelf->_a);
NSLog(@"%zd", _a);
};
现在很清楚,最后一行从块外捕获self
。你命名它的方式,使区分self
(在块中声明的局部变量)与从其范围外捕获的self
更加难以区分。
答案 1 :(得分:0)
引用_a是对封闭范围内的实例变量的直接引用。这隐含地抓住了自我。它没有调用属性的getter / setter。它直接指向实例变量。
不要在一个持续存在的区域内做到这一点。 ("逃避"阻止,因为Apple已经开始调用它。)使用@Sosiowaty在他的回答中显示的weakSelf / strongSelf语法。