0

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

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

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

回调是这样创建的

@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:,并在 dispatch_async 块中触发,例如 this

__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:内部使用的一种便利类别方法。有人对我在这里可能做错了什么有一些见解吗?

4

1 回答 1

0

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

于 2013-10-02T23:49:10.197 回答