如何避免使用__block和完成块的内存泄漏

普纳

我有一种情况,需要使用访问该对象的完成块来初始化对象。为了使这种访问成为可能,该对象被定义为__block。问题在于该对象永远不会被释放。看下面的例子。

- (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath 
{
    __block MyViewController* myViewController = [[MyViewController] alloc] initWithCompletion:^{
        if (indexPath.row == 0) {
            [myViewController.navigationController 
                pushViewController:[[GoodViewController alloc] init]
                animated:YES
            ];
        } else if (indexPath.row == 1) {
            [myViewController.navigationController 
                pushViewController:[[BadViewController alloc] init]
                animated:YES
            ];
        }
    }];
}

一切都很好,只是从导航堆栈中弹出myViewController的dealloc不会被调用。当我删除__block时,将最终调用dealloc,但这样做会阻止我访问其完成块内的myViewController。如何在没有内存泄漏的情况下访问其自己的完成块中的对象?

乔迪·哈金斯(Jody Hagins)

您的视图控制器将保留该块,而该块将保留myViewController,从而创建一个保留周期。

像这样想吧...视图控制器在模块周围放置了一条皮带,以防止它在视图控制器完成之前被取消分配。该块将皮带束缚在视图控制器周围,以防止其取消分配,直到完成该块为止。

在另一个先释放其引用之前,任何一个都不会释放对另一个的引用,从而保持一个循环。

有多种方法可以避免保留周期,具体取决于您使用该块的方式。

在您的情况下,我将让完成块传回该块所连接的视图控制器。这将很容易避免保留对象本身的需要。

MyViewController* myViewController = [[MyViewController] alloc]
    initWithCompletion:^(MyViewController *viewController) {
    if (indexPath.row == 0) {
        [viewController.navigationController 
            pushViewController:[[GoodViewController alloc] init]
                      animated:YES
        ];
    } else if (indexPath.row == 1) {
        [viewController.navigationController 
            pushViewController:[[BadViewController alloc] init]
                      animated:YES
        ];
    }
}];

在MyViewController类中,您只需使用...调用该块。

if (_completionBlock) _completionBlock(self);

在设计界面时,请尝试使其尽可能易于使用,而不会对用户造成不适当的限制。在这种情况下,通过将控制器作为参数传递回该块,可以让用户编写不必担心在控制器和块之间创建的保留周期的代码。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何使用ShellExecuteEx避免内存泄漏?

如何使用CTFontCreateWithGraphicsFont避免内存泄漏?

使用 arraylist 时如何避免内存泄漏?

如何使用View避免内存泄漏

SKAction.runAction()完成块的内存泄漏(关闭)

这里如何避免内存泄漏?

如何避免jQuery的内存泄漏?

如何避免这种内存泄漏?

Node和RxJs:如何避免长时间的内存泄漏?

如何通过使用pthread_cancel避免内存泄漏?

在完成块中进行调用操作而不会发生内存泄漏

关闭QWebView时如何避免内存泄漏?

如何避免此功能导致内存泄漏?

如何避免回调中的内存泄漏?

如何避免PHP 5.4中的内存泄漏?

如何避免RecyclerView ViewHolder中的内存泄漏?

使用 WeakReference Android 避免内存泄漏

使用C ++中的Delete避免内存泄漏

FLEX:避免内存泄漏

在ARC中,子对象如何告知父对象我已经完成,请释放我(以避免内存泄漏)

如何在Android中释放内存以避免内存泄漏

结合使用多处理和请求时,是否有更好的方法来避免内存泄漏?

如何使用Vue.js中的JavaScript避免来自cloneNode的内存泄漏

如何避免在Angular 9中使用复杂的RxJS管道发生内存泄漏?

在C中使用concat字符串指针时如何避免内存泄漏

避免短暂视图模型上的WeakEventManager和内存泄漏

如何使用搜索栏从 SwiftUI 视图调用完成块?

如何避免android中mvvm架构中的内存泄漏

如何避免SwiftUI + Combine Timer Publisher参考周期/内存泄漏?