在此块中强烈捕获“发现”可能会导致保留周期

时间:2013-12-10 14:40:57

标签: objective-c-blocks

我有这段代码:

- (void) resotreEntitySelectionForHistoryObject:(CoreDataHistoryObject *)historyObject {
    OutlineViewNode *(^__block find)(OutlineViewNode *, NSString *) = ^OutlineViewNode *(OutlineViewNode *node, NSString *title) {
        if ([node.title isEqualToString:title]) {
            return node;
        }

        for (OutlineViewNode *child in node.childs) {
            OutlineViewNode *result = find(child, title);
            if (result) {
                return result;
            }
        }

        return nil;
    };

    OutlineViewNode *node = find(self.rootNode, historyObject.name);

    if (node) {
        [self.dataSourceList selectRowIndexes:[NSIndexSet indexSetWithIndex:[self.dataSourceList rowForItem:node]] byExtendingSelection:NO];
    }
}

我得到了这个编译器警告:

  • CoreDataUtility / CoreDataUtil / MFLMainWindowController.m:230:39:在此块中强烈捕获'find'可能会导致保留周期*

这一行是“OutlineViewNode * result = find(child,title);”

我知道只需创建方法而不是块的解决方案。但现在这让我想到你怎么能从块中返回一个值。

供您参考,您可以在此处查看完整的源代码:

https://github.com/yepher/CoreDataUtility/blob/master/CoreDataUtil/MFLMainWindowController.m#L224

1 个答案:

答案 0 :(得分:1)

该块捕获变量find,该变量设置为指向块。因此该块具有对自身的强引用,因此它具有保留周期。

要做得对,你需要两个指向块的变量,一个弱,一个强。该块将捕获弱块,以便没有强烈的自身引用。强者必须保持对该块的引用。

OutlineViewNode *(^find)(OutlineViewNode *, NSString *);
__block OutlineViewNode *(^ __weak findWeak)(OutlineViewNode *, NSString *);
findWeak = find = ^OutlineViewNode *(OutlineViewNode *node, NSString *title) {
    if ([node.title isEqualToString:title]) {
        return node;
    }

    for (OutlineViewNode *child in node.childs) {
        OutlineViewNode *result = findWeak(child, title);
        if (result) {
            return result;
        }
    }

    return nil;
};

OutlineViewNode *node = find(self.rootNode, historyObject.name);