Reputation: 82
I'm implementing a simple twitter client for the iPhone using a UITableView. I fetch the picture of each twitter user in my feed when their cell appears in tableView: cellForRowAtIndexPath:
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;
});
});
Here is the code to fetch the image:
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];
Here is the error I'm getting:
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...
I think it's also worth mentioning that this happens when I scroll through the tableview very quickly when it hasn't been populated yet.
I would like the main UI to update upon completion of the download. The actual twitter app for iPhone does this quite well.
Any suggestions?
Upvotes: 2
Views: 601
Reputation: 1268
You're using GCD fine, your crash is happening because you're calling dataWithContentsOfURL in a background thread, which is not thread safe.
See: Does -dataWithContentsOfURL: of NSData work in a background thread?
Upvotes: 1
Reputation: 57149
What’s the crash? A pretty standard pattern for things like this is
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
});
});
Upvotes: 4