来自被调用方法的块和自我

时间:2011-12-02 08:16:17

标签: objective-c memory-management objective-c-blocks

好的,所以我理解如何避免self使用块保留周期,当我从嵌套在嵌套深度较深的块中的方法向自己发送消息的情况时如何:

- (void)methodA {
    __block MyClass *blockSelf = self;
    [someObject block:^{
        [blockSelf methodB];
    }];
}

- (void)methodB {
    ...
    [self methodC];
    ...
}

- (void)methodC {
}

在这种情况下,[blockSelf methodB]没问题,但是从[self methodC]发送methodB会导致保留周期吗?无法在任何地方找到答案...

1 个答案:

答案 0 :(得分:8)

那里没有保留周期。在方法内定义块文字时,块可以捕获的上下文仅限于该方法中可见的内容。在您的示例中:

- (void)methodA {
    __block MyClass *blockSelf = self;
    [someObject block:^{
        [blockSelf methodB];
    }];
}

块文字,即:

^{
    [blockSelf methodB];
}

能够看到以下内容:

  1. self_cmd,它们是每个Objective-C方法中可用的隐藏参数。如果-methodA有正式参数,那么Block文字也可以看到它们;
  2. 函数/方法块内的任何块范围变量,即方法内的每个局部变量,并且在定义块文字的位置可见。在示例中,-methodA中唯一的局部变量是blockSelf,因为它是__block - 合格的,不会保留;
  3. 任何文件范围变量(也称为全局变量)。
  4. 块文字不知道(并且在一般情况下,无法察觉)其他函数/方法内部发生的事情,因此块文字不会捕获被调用函数/方法内的任何上下文。您只需要担心定义块文字的方法。

    当使用闭包/ lambdas(即^{})和引用C块时的小写块(即{})时,我正在使用Apple的大写Block的约定。