Caputure属性值导致通过_property样式保留循环

时间:2016-11-25 14:35:35

标签: ios objective-c retain-cycle

我有一个班级,有一个块:

@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)));
}

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

2 个答案:

答案 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语法。