以下这段代码是我在网络上找到的,作用使用UITableView控件进行异步加载图片。
- - (UITableViewCell *)tableView:(UITableView *)tableView
- cellForRowAtIndexPath:(NSIndexPath *)indexPath
- {
- UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"tag"];
- if (cell==nil)
- {
- cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
- reuseIdentifier:@"tag"] autorelease];
- }
- //表格设计
- NSDictionary* one = [array objectAtIndex:indexPath.row];
- cell.textLabel.text = [one objectForKey:@"title"];
- cell.detailTextLabel.text = [one objectForKey:@"content"];
- [NSThread detachNewThreadSelector:@selector(updateImageForCellAtIndexPath:) toTarget:self withObject:indexPath];
- return cell;
- }
- - (void)updateImageForCellAtIndexPath:(NSIndexPath *)indexPath
- {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- UIImage *image = [self getImageForCellAtIndexPath:indexPath];
- UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
- [cell.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
- [image release];
- [pool release];
- }
- -(UIImage *)getImageForCellAtIndexPath:(NSIndexPath *)indexPath
- {
- id path = [[array objectAtIndex:indexPath.row] objectForKey:@"image"];
- NSURL *url = [NSURL URLWithString:path];
- NSData *data = [NSData dataWithContentsOfURL:url];
- UIImage *image = [[UIImage alloc] initWithData:data cache:NO];
- return image;
- }
本来以为这样就OK了,可是当运行时,只要不断的上下滚动,就会经常crash掉。在Debug Console中显示是因为数组越界访问。后来,经调查是由于下面这句话引起的:
- UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath
也就是说,想要读取或设置某个控件的属性时,必须在主线程中执行。否则,容易出现异常。
下面的代码除了改进了这个BUG之外,还将已经下载过的图片数据保存在内存中,当下次需要用时,可以直接使用,而不必再次下载。
- - (void)downloadImageForCellAtIndexPath:(NSIndexPath*)indexPath
- {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- NSUInteger row = [indexPath row];
- TimeLineData *data = [blogArray objectAtIndex:row];
- if(data.imgData == nil)
- {
- UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[data userImg]]]];
- data.imgData = image;
- [image release];
- }
- [self performSelectorOnMainThread:@selector(updateImageForCellAtIndexPath:) withObject:indexPath waitUntilDone:NO];
- [pool release];
- }
- - (void)updateImageForCellAtIndexPath:(NSIndexPath*)indexPath
- {
- NSUInteger row = [indexPath row];
- TimeLineData *data = [blogArray objectAtIndex:row];
- BlogTableCell *cell = (BlogTableCell*)[blogView cellForRowAtIndexPath:indexPath];
- [cell.cellHeadImg setImage:data.imgData];
- }