【问题标题】:retain cycle inside of block with local scope ivars在具有本地范围 ivars 的块内保留循环
【发布时间】:2013-09-13 12:52:38
【问题描述】:

对于我的一生,我无法弄清楚这里发生了什么。

作为一个概述,我有一个应用程序,我创建了一个自定义导航栏、一个自定义包含视图控制器和回调,以告诉我何时在各个视图控制器中完成了昂贵的进程(例如大量图片)。

当导航到子视图控制器时,在我的容器视图控制器中,会在子视图控制器上设置回调以在完成一组昂贵的进程后调用过渡动画。

回调是这样创建的

@interface UIViewController (CallBack)

typedef void (^CompletionBlock)(void);

@property (nonatomic, copy) CompletionBlock callBackBlock;

- (void)doneLoadingImages;

@end

static char const *const CompletionBlockTagKey = "CompletionBlockTag";

@implementation UIViewController (CallBack)
@dynamic callBackBlock;

- (CompletionBlock)callBackBlock
{
    return objc_getAssociatedObject(self, CompletionBlockTagKey);
}

- (void)setCallBackBlock:(CompletionBlock)callBackBlock
{
    objc_setAssociatedObject(self, CompletionBlockTagKey, callBackBlock, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

- (void)doneLoadingImages
{
    [self callBackBlock]();

    self.callBackBlock = nil;
}

@end

这些回调在通过addChildViewcontroller:添加子视图控制器之前设置,并在诸如this之类的dispatch_async块中触发

__block __weak ThisUIViewController *me = self;

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    UIImage *image1 = [UIImage imageForNibFromFileName:@"picture_name"];

    dispatch_async(dispatch_get_main_queue(), ^{
        me.imageViewToSet.image = image1;

        [me doneLoadingImages];
    });
});

第一次通过我的导航代码从我的容器视图控制器调用 UIViewcontroller 时,此过程会顺利进行。根据分析器的说法,在我离开它表明我的保留计数为 0 后,它也会正确转储内存。

但是,当我再次导航到同一个 UIViewcontroller 时发生的情况是图像加载速度超快,doneLoadingImages 也被超快调用,导致我的主线程挂起并导致 UI 变得无响应直到一切都设置好 UI。

我的imageForNibFromFileName: 方法只是一种在内部使用imageForContentsOfFile: 的便利类别方法。有人知道我在这里可能做错了什么吗?

【问题讨论】:

    标签: objective-c objective-c-blocks retaincount retain-cycle


    【解决方案1】:

    事实证明这不是保留问题。我不确定为什么,但我不得不将图像从 global_queue 中分离到它们自己的 dispatch_async 调用中,而不是将它们全部链接到一个异步块中。如果有人解释为什么必须这样做或后台发生了什么,将不胜感激。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-26
      • 2021-11-23
      • 1970-01-01
      • 1970-01-01
      • 2011-02-13
      相关资源
      最近更新 更多