[英]Caputure property value lead to retain cycle through _property style
I have a class, there's a block proper: 我有一堂课,这里有一个块:
@property(nonatomic, strong) void (^hehe)();
In the init method, I do the following work: 在init方法中,我做了以下工作:
__weak test *weakSelf = self;
self.hehe = ^{
test *self = weakSelf;
NSLog(@"%zd", self.a);
NSLog(@"%zd", self->_a);
NSLog(@"%zd", _a);
};
What is the difference between the last two line in the block. 该块的最后两行之间有什么区别。
I thought self->_a
is equals to _a
. 我以为self->_a
等于_a
。
But the Xcode shows warning on the last line: 但是Xcode在最后一行显示警告:
Caputuring self strongly in this block is likely to lead a retain cycle
Edit: 编辑:
I know the local self and the global self is not the same. 我知道本地自我和全球自我是不一样的。 How the os distinguish the difference. 操作系统如何区分差异。 I used clang to rewrite the code, and get the following: 我使用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)));
}
The last two line is used the same self... 最后两行使用相同的self ...
Because it means a different self
. 因为这意味着不同的self
。 A quick rename will make everything clear : 快速重命名将使一切变得清晰:
__weak test *weakSelf = self;
self.hehe = ^{
test *strongSelf = weakSelf;
NSLog(@"%zd", strongSelf.a);
NSLog(@"%zd", strongSelf->_a);
NSLog(@"%zd", _a);
};
Now it is clear, that the last line captures self
from outside the block. 现在很清楚,最后一行从块外部捕获了self
。 The way you had it named, made it harder to differentiate between the self
that was a local variable declared inside a block, and the self
that was captured from outside its scope. 你有它命名方式,使得它更难于区分self
,这是一个块内声明的局部变量,并self
认为是从它的范围之内拍摄的。
Referring to _a is a direct reference to an instance variable from the enclosing scope. 引用_a是从封闭范围直接引用实例变量。 That implicitly captures self. 那暗含了自我。 It doesn't invoke the property's getter/setter. 它不会调用属性的getter / setter。 It points directly to the instance variable. 它直接指向实例变量。
Don't do that from inside a block that persists. 不要在一个持久的块内执行此操作。 (An "escaping" block, as Apple has started calling it.) Use the weakSelf/strongSelf syntax @Losiowaty showed in his answer. (Apple开始调用它时,这是一个“转义”块。)使用他的答案中显示的weakSelf / strongSelf语法@Losiowaty。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.