iphoneuitableviewnsthread

NSThread, UITableViewCell and Image


I am having some problem with my UITableView. I am downloading the data and setting up the cells like usual, but this time with the NSThread added.

First I will call ASIHTTPRequest in my view did load

Then in - (void)requestFinished:(ASIHTTPRequest *)request I will add the url of the thumbnail into an NSMutableArray

 NSString *photoURLString = [NSString stringWithFormat:@"http://some.url.com/img/%@",[thearray objectForKey:@"tn_url"]];    
[thumbNailURL addObject:(photoURLString)];

And in the cellForRowAtIndexPath: where I am setting up other data to display, I will call my NSThread

[NSThread detachNewThreadSelector:@selector(loadImage:) toTarget:self withObject:indexPath];

And in my loadImage thread

- (void) loadImage: (NSIndexPath*) indexPath{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *iconURL = [thumbNailURL objectAtIndex:indexPath.row];
NSURL *url = [NSURL URLWithString:iconURL]; 
UIImage *icon = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
cellImageView = [[UIImageView alloc] initWithFrame:CGRectMake(11.0, 6.0, 61.0, 50.0)];
[cellImageView setImage:icon];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
[cell.contentView performSelectorOnMainThread:@selector(addSubview:) withObject:cellImageView waitUntilDone:NO];
[pool drain];

}

All the data and image loaded just fine, but if I scroll faster up and down , the application will hang with the following error

[1997:7a1f] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 6 beyond bounds [0 .. 5]'    (0x31312d2f 0x345f50e3 0x3127d1b1 0x35aefc1d 0xf4dd 0x333ffb51 0x3347c67b 0x366af589 0x366b2310) terminate called throwing an exceptionProgram received signal:  “SIGABRT”.

It would be great if anyone could show me the correct configuration if I am wrong, as I have been trying different approaches for the past 3 days already.


Solution

  • A couple things.

    First, I would recommend you consider using something like SDWebImage for async image downloading (looks like Olivier Poitrey is the original author). Github repository here: https://github.com/rs/SDWebImage. I use it for this very purpose and it's great.

    That said, I see a few things here.

    1) You don't seem to be checking if the cell image is already set... no need to re-download the image if you've already got it. You might get away with this since dataWithContentsOfUrl might offer some caching, but I'm not sure.

    2) I can't tell from the code here, but you need to be sure you don't allow the table view to load it's data until after requestFinished is called. Otherwise you'll have a race condition that could cause the type of error you are seeing. Consider setting the tableView's data source in the requestFinished method and then calling reloadData. Otherwise, do as downed suggested and just prefill the URL array with [NSNull null] objects.