保留周期 - 需要确认

时间:2014-04-30 17:47:21

标签: ios memory-management

我一直在讨论保留周期,但大多数人都在谈论明确定义一个块并对其进行强有力的引用。他们都没有谈到只是传递一个内联块。 我的理解是,只是将函数中的块作为参数传递,不会创建强引用。但我只是想确保我没有误解。

所以问题是: 在成员函数中传递块是否会创建强引用?

    [self someFunctionWithCompletionCallback:^{
        [self completionFunctionality];
    }];

在这种情况下,自我保持对传递的块的强引用?

这将决定我是否需要传递weakSelf。

由于

4 个答案:

答案 0 :(得分:3)

当您在块体中调用[self completionFunctionality];时,它(块)会保留self,因此会创建strong引用。当块的执行完成时,它将超出范围,因此它将从堆栈中删除并阻止对self的强引用。这意味着在块执行完成之前,self无法解除分配。所以它不是retain cycle的共同理解。

答案 1 :(得分:3)

这取决于someFunctionWithCompletionCallback:的作用。例如,如果该方法将该块存储在强成员变量中,则会导致保留周期。如果方法在执行期间仅调用块并且不存储它,则不会创建永久保留周期。

请注意以下内容:

- (void)someFunctionWithCompletionCallback:(void (^)())completionBlock {
    dispatch_async(^{ completionBlock() }); 
}

暂时保留self(直到异步调度完成),因为dispatch_async将保留其块,这将保留完成块,这将保留self。

答案 2 :(得分:3)

请记住,循环的定义是A-> B-> A(其中' - >'表示'保留')。在您的问题中,B是一个块,A是定义块文字的对象。 B-> A肯定是正确的,因为块保留在它们中引用的对象而B指的是A.

但是A-> B?这取决于A.只是传递一个对象并不会保留它(想象一下如果是这样的话,无限保留到处都是!)。那么A如何处理B?如果A复制或保留B,则A-> B,并且您有一个周期。如果没有,你就不会。

答案 3 :(得分:1)

此代码不会创建保留周期。如果块例如是强或复制属性,那么它将是保留周期