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方法中執行此操作。