我正在尝试异步下载UITableViewCell的图像,但它目前正在为每个单元格设置相同的图像。
请告诉我代码的问题:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
SearchObject *so = (SearchObject *)[_tableData objectAtIndex:indexPath.row];
cell.textLabel.text = [[[[so tweet] stringByReplacingOccurrencesOfString:@""" withString:@"\""] stringByReplacingOccurrencesOfString:@"<" withString:@"<"] stringByReplacingOccurrencesOfString:@">" withString:@">"];
cell.detailTextLabel.text = [so fromUser];
if (cell.imageView.image == nil) {
NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:[so userProfileImageURL]]];
NSURLConnection *conn = [NSURLConnection connectionWithRequest:req delegate:self];
[conn start];
}
if ([_cellImages count] > indexPath.row) {
cell.imageView.image = [UIImage imageWithData:[_cellImages objectAtIndex:indexPath.row]];
}
return cell;
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[_cellData appendData:data];
[_cellImages addObject:_cellData];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[self.tableView reloadData];
}
答案 0 :(得分:1)
您将从下载到同一数据对象的每个图像中追加数据。因此,在最好的情况下,数据对象最终会得到图像#1的数据,紧接着是图像#2的数据,依此类推;图像解码器显然是在数据块中取第一个图像并忽略后面的垃圾。您似乎也不知道NSURLConnections'connection:didReceiveData:
不一定按照连接启动的顺序调用,connection:didReceiveData:
每个连接可以被调用零次或多次(如果您的图像可能会被调用)超过几个kibibytes),并且不保证按顺序为表中的每个单元调用tableView:cellForRowAtIndexPath:
。所有这些都将完全搞砸你的_cellImages
阵列。
要做到这一点,你需要为每个连接都有一个单独的NSMutableData实例,你只需要将它添加到_cellImages
数组中一次,并将其添加到行的正确索引而不是任意下一个可用指数。然后在connection:didReceiveData:
中你需要找出要附加的正确的NSMutableData实例;这可以通过使用连接对象(使用valueWithNonretainedObject:
包装在NSValue中)作为NSMutableDictionary中的键,或使用objc_setAssociatedObject
将数据对象附加到连接对象,或者通过自己创建为您处理NSURLConnection的所有管理的类,并在完成时将数据对象交给您。
答案 1 :(得分:0)
我不知道这是否会导致问题,但在connection:didReceiveData:
方法中,您只是将图像数据附加到数组中;你应该以这样一种方式存储图像数据,你可以将它链接到它应该显示的单元格。一种方法是使用NSMutableArray
填充一堆[NSNull]
s,然后在连接完成加载时替换适当索引处的null
值。
此外,当连接尚未完成加载时,您将_cellData
附加到_cellImages
数组,您应该只使用connection:didFinishLoading
方法执行此操作。