我正在构建一个iOS应用程序,它将XML项目添加到TableView(当然还有其他内容)。如果文章的缩略图字段为空,我想在TableView单元格中显示文章的缩略图或默认占位符。
下面的代码添加了文章中的缩略图,但随后导致滚动停顿不前。如果我只为每个单元格使用占位符图像,一切都很好。我猜我可能没有使用最理想的方法来添加缩略图,不确定这是否会导致问题。
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"idCellNewsTitle"];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"idCellNewsTitle"];
}
NSDictionary *dict = [self.arrNewsData objectAtIndex:indexPath.row];
cell.imageView.image = [UIImage imageNamed:@"holder-small.jpg"];
cell.textLabel.text = [dict objectForKey:@"title"];
cell.detailTextLabel.text = [dict objectForKey:@"pubDate"];
if ([dict objectForKey:@"thumbnail"] != nil) {
NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString: [dict objectForKey:@"thumbnail"]]];
if (imgData) {
UIImage *image = [UIImage imageWithData:imgData];
if (image) {
cell.imageView.image = image;
}
}
}
return cell;
}
在最新的XCode中进行编码,在模拟器和较新的iPod上进行测试 - 结果与两者相同。在运行应用程序期间没有警告或错误,当滚动和内存保持在16 MB左右时,CPU峰值为1%。
更新 - 视频 这是一个视频,展示了这个问题,以便将来与之比较 - 第一个例子是占位符,第二个是没有占位符。 Video on YouTube
答案 0 :(得分:2)
替换cellForRowAtIndexPath中的代码:
此行if ([dict objectForKey:@"thumbnail"] != nil)
这样你就可以在后台加载每个图像,加载后相应的单元格会在mainThread上更新。
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) {
NSData *imgData = NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString: [dict objectForKey:@"thumbnail"]]];
if (imgData) {
UIImage *image = [UIImage imageWithData:imgData];
dispatch_sync(dispatch_get_main_queue(), ^(void) {
UIImage *image = [UIImage imageWithData:imgData];
if (image) {
cell.imageView.image = image;
}
});
});
答案 1 :(得分:0)
使用GCD获取图像
// Fetch using GCD
dispatch_queue_t downloadThumbnailQueue = dispatch_queue_create("Get Photo Thumbnail", NULL);
dispatch_async(downloadThumbnailQueue, ^{
UIImage *image = [self getTopPlacePhotoThumbnail:photo];
dispatch_async(dispatch_get_main_queue(), ^{
UITableViewCell *cellToUpdate = [self.tableView cellForRowAtIndexPath:indexPath]; // create a copy of the cell to avoid keeping a strong pointer to "cell" since that one may have been reused by the time the block is ready to update it.
if (cellToUpdate != nil) {
[cellToUpdate.imageView setImage:image];
[cellToUpdate setNeedsLayout];
}
});
});