阻止递归并中断保留周期 [英] Block recursion and breaking retain cycle

查看:69
本文介绍了阻止递归并中断保留周期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了更好地说明这个问题,请考虑以下简化的块递归形式:

To better illustrate the question, consider the following simplified form of block recursion:

__block void (^next)(int) = ^(int index) {
    if (index == 3) {
        return;
    }
    int i = index;
    next(++i);
};
next(0);

XCode(启用ARC)警告说:"在此块中强烈捕获'next'可能会导致保留周期."

XCode (ARC-enabled) warns that "Capturing 'next' strongly in this block is likely to lead to a retain cycle".

同意.

问题1 :通过将块本身设置为nil,这种方式是否可以成功打破保留周期:

Question 1: Would the retain cycle be successfully broken by setting the block itself to nil, in this fashion:

__block void (^next)(int) = ^(int index) {
    if (index == 3) {
        next = nil; // break the retain cycle
        return;
    }
    int i = index;
    next(++i);
};
next(0);

(注意:您仍然会收到相同的警告,但可能是不必要的)

(Note: you'd still get the same warning, but perhaps it is unwarranted)

问题2 :更好的块递归实现是什么?

Question 2: What would be a better implementation of block recursion?

谢谢.

推荐答案

要完成无保留周期的递归块执行,您需要使用两个块引用-一个弱引用和一个强引用.因此,对于您的情况,代码如下所示:

To accomplish the retain-cycle-free recursive block execution, you need to use two block references - one weak and one strong. So for your case, this is what the code could look like:

__block __weak void (^weak_next)(int);
void (^next)(int);
weak_next = next = ^(int index) {
  if (index == 3) {
    return;
  }
  int i = index;
  weak_next(++i);
};
next(0);

请注意,该块捕获了弱块引用(weak_next),而外部上下文捕获了强引用(下一个)以保持该块.两个引用都指向同一块.

Note that the block captures the weak block reference (weak_next), and the external context captures the strong reference (next) to keep the block around. Both references point to the same block.

有关此模式的另一个示例,请参见 https://stackoverflow.com/a/19905407/1956124 使用块递归.此外,以下文章的评论部分中的讨论也与此相关: http://ddeville.me/2011/10/recursive-blocks-objc/

See https://stackoverflow.com/a/19905407/1956124 for another example of this pattern, which also uses block recursion. In addition, the discussion in the comments section of the following article is relevant here as well: http://ddeville.me/2011/10/recursive-blocks-objc/

这篇关于阻止递归并中断保留周期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆