完成后台线程后更新UI

时间:2011-08-10 22:48:59

标签: iphone objective-c cocoa-touch

我正在使用UITableView为iPhone实现一个简单的Twitter客户端。当我们的单元格出现在tableView:cellForRowAtIndexPath:

时,我会在我的Feed中获取每个Twitter用户的图片
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    UIImage *profileImage = [tweet.user getProfileImageDataInContext:self.fetchedResultsController.managedObjectContext];
    dispatch_async(dispatch_get_main_queue(), ^{
        cell.imageView.image = profileImage;
    });
});

以下是获取图片的代码:

    if (!self.profileImage) 
{
    sleep(2);
    self.profileImage = [NSData dataWithContentsOfURL:[NSURL URLWithString:self.profileImageURL]];
    //// if we recently scheduled an autosave, cancel it
    [TwitterUser cancelPreviousPerformRequestsWithTarget:self selector:@selector(autosave:) object:context];
    // request a new autosave in a few tenths of a second
    [TwitterUser performSelector:@selector(autosave:) withObject:context afterDelay:0.2];
}
return [UIImage imageWithData:self.profileImage];

这是我得到的错误:

twitterClient[10743:15803] bool _WebTryThreadLock(bool), 0x59bac90: Tried to obtain the web lock from a thread other than the main thread or the web thread. This may be a result of calling to UIKit from a secondary thread. Crashing now...

我认为值得一提的是,当我尚未填充表格视图时,会发生这种情况。

我希望在完成下载后更新主UI。 iPhone的实际Twitter应用程序做得非常好。

有什么建议吗?

2 个答案:

答案 0 :(得分:4)

什么是撞车事故?对于像这样的事情,一个非常标准的模式是

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // do background stuff
    dispatch_async(dispatch_get_main_queue(), ^{
        // do main-queue stuff, like updating the UI
    });
});

答案 1 :(得分:1)

你正在使用GCD,你的崩溃正在发生,因为你在后台线程中调用dataWithContentsOfURL,这不是线程安全的。

请参阅:Does -dataWithContentsOfURL: of NSData work in a background thread?