2016-11-25 55 views
0

我有一个类,有正确的模块: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


编辑:

我知道当地的自我和总体自我是不一样的。 OS如何区分差异。我用铛重写代码,并得到如下:

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

你的问题是为什么有第三行警告,但不是第二行? –

+0

我知道第三行的块捕捉全局自我。我用clang把c-c改成了objective-c,第二行和第三行看起来是一样的。系统如何区分它们? – leizh00701

+0

铿锵重写并不总是做正确的事 – newacct

回答

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(它是从范围之外捕获的)。

+0

我编辑了这个问题 – leizh00701

0

参考_a是从封闭范围直接引用实例变量。这隐含地捕捉自我。它不会调用属性的getter/setter。它直接指向实例变量。

不要从持续存在的块内执行此操作。 (苹果公司已经开始称它为“逃跑”模块)。使用@Sosoowowy在他的回答中显示的weakSelf/strongSelf语法。