ios – 在dispatch_get_main_queue()上更新UI

前端之家收集整理的这篇文章主要介绍了ios – 在dispatch_get_main_queue()上更新UI前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个问题与使用队列在主线程上更新UI有关.

那么,假设我们创建了一个UITableView,它显示了一个带有UIImageView的UILabel. UIImage的异步加载在prepareCellfor ..使用:

dispatch_async(t_queue,^{
   //load image
   //dispatch_async(dispatch_get_main_queue(),^{
     cell.imageView = image;
   }
 });

但是,当块获取图像时,用户按下该单元格的一个单元格(或导航视图控制器上的后退按钮)一个Load de DetailViewController(或返回应用程序).

我的问题是:当块启动主线程来更新单元格的imageView时会发生什么?它正在尝试更新未加载在窗口上的UIView,甚至可以卸载…

谢谢

解决方法

这是一个很好的问题.而使用ARC的答案基本上就是块本身保留对象,这样它将在后面.这是微妙的记忆障碍之一.如果这个单元格来自的UITableView被取消分配并释放其所有的单元格,那么这个单元格将被保留(尽管是屏幕外),并且将分配cell.imageView = image;完成后就会被释放.

我是一个控制实验的大粉丝,并开始测试这个,但是一个UITableView有许多移动部分(没有双关语).所以我创建了一个非常简单的实验,使用一个简单的NSObject子类如下:

@implementation SayHello
-(void)sayHello{
    NSLog(@"Hello");
}
-(void)dealloc{
    NSLog(@"SayHello dead");
}
@end

显然,这个类旨在给我一个函数调用一个块(sayHello),并在去分配时产生一个NSLog.

我这样测试:

SayHello *hello = [[SayHello alloc] init];
dispatch_async(dispatch_get_global_queue(0,0),^{
    double delayInSeconds = 30.0;
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW,delayInSeconds * NSEC_PER_SEC);
    dispatch_after(popTime,dispatch_get_main_queue(),^(void){
        [hello sayHello];
    });
});

30秒给出最懒惰的runloop时间来释放“hello”对象(如果实际上没有保留).但是对于这30秒,控制台是静音的. 30秒过后,我会立即收到“Hello”,然后点击“SayHello dead”消息.

那么这是一个“骗子”呢?嗯,显然如果你没有意识到Block / ARC正在做这件事,那么可能会最终保持你以为应该去的东西.而且你的例子是UITableViewCell;如果您的单元格显示一次并通过网络向图像发送请求,但是当块等待图像时,单元格被重用?现在有一个第二个块参考该单元格尝试设置其图像.那么现在你有一个比赛,失败者会决定显示什么图像.

原文链接:https://www.f2er.com/iOS/329579.html

猜你在找的iOS相关文章