0

我想为UITableViewCell异步下载图像,但它当前正在为每个单元设置相同的图像。异步下载的问题UITableView

请你能告诉我我的代码的问题:

- (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:@"&quot;" withString:@"\""] stringByReplacingOccurrencesOfString:@"&lt;" withString:@"<"] stringByReplacingOccurrencesOfString:@"&gt;" 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]; 
} 

回答

1

您正在追加下载到相同数据对象的每个图像的数据。因此,在最好的情况下,数据对象以图像#1的数据结束,紧接着是图像#2的数据,等等。图像解码器显然是采取大块数据中的第一个图像,并忽略后面的垃圾。您似乎也不知道NSURLConnections的connection:didReceiveData:未必会按连接开始的顺序调用,因此可以将connection:didReceiveData:称为每个连接零次或多次(并且如果您的映像超过几千字节,则可能会被调用)并且tableView:cellForRowAtIndexPath:不能保证为表中的每个单元格按顺序调用。所有这些都将完全搞砸你的_cellImages阵列。

要做到这一点,您需要为每个连接都有一个单独的NSMutableData实例,并且您只需将其添加到_cellImages数组中一次,并且在该行的正确索引处而不是在任意下一个可用索引处。然后在connection:didReceiveData:你需要找出正确的NSMutableData实例追加到;这可以通过使用连接对象(包装在NSValue中,使用valueWithNonretainedObject:)作为NSMutableDictionary中的键或使用objc_setAssociatedObject将数据对象附加到连接对象来完成,或者通过使自己成为一个处理所有对为你提供NSURLConnection,并在完成时交给你数据对象。

0

我不知道这是否是引起问题或没有,但在你的connection:didReceiveData:方法你只是附加的图像数据阵列;你应该以这种方式存储图像数据,以便将它链接到它应该显示的单元格。一种方法是使用一个NSMutableArray填充一堆[NSNull] s,然后将null的值替换为连接完成加载时的适当索引。

另外,当连接尚未完成加载时,您正在将_cellData附加到_cellImages阵列,您应该只在connection:didFinishLoading方法中执行此操作。