2011-10-21 69 views
8

我有一個UITableView自定義單元格。我使用Grand Central Dispatch異步加載圖像。一切工作正常,但當我向下滾動,以前加載的圖像顯示,直到新的圖像下載。這裏是我的代碼:GCD UITableView異步加載圖像,加載錯誤的單元格,直到新圖像下載

if (![[NSFileManager defaultManager] fileExistsAtPath:[path stringByAppendingPathComponent:@"image.png"]]) 
{ 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
    dispatch_async(queue, ^{ 
     NSString *url=[pat stringByAppendingPathComponent:@"comments.txt"]; 
     NSString *u=[NSString stringWithContentsOfFile:url encoding:NSUTF8StringEncoding error:nil]; 
     NSURL *imageURL=[NSURL URLWithString:u]; 
     NSData *image=[NSData dataWithContentsOfURL:imageURL]; 
     [image writeToFile:[pat stringByAppendingPathComponent:@"image.png"] atomically:YES]; 
     dispatch_sync(dispatch_get_main_queue(), ^{ 
      cell.imageView.image=[UIImage imageWithContentsOfFile:[pat stringByAppendingPathComponent:@"image.png"]]; 
      [cell setNeedsLayout]; 
      NSLog(@"Download"); 
     }); 
    }); 
} 
else 
{ 
    NSLog(@"cache"); 
    cell.imageView.image=[UIImage imageWithContentsOfFile:[pat stringByAppendingPathComponent:@"image.png"]]; 
} 

任何建議表示讚賞。 P.S.我重用這些單元格

回答

18

而不是捕獲細胞需要捕獲的索引路徑,然後讓細胞回用:

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 

這樣一來,如果現在的電池是關閉屏幕,你會得到零背部和圖像不會被設置在錯誤的單元格上。

dispatch_async()cell.imageView.image=somePlaceholderImage之後,您需要添加的另一件事。

例如爲:

if (![[NSFileManager defaultManager] fileExistsAtPath:[path stringByAppendingPathComponent:@"image.png"]]) 
{ 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
    dispatch_async(queue, ^{ 
     NSString *url=[pat stringByAppendingPathComponent:@"comments.txt"]; 
     NSString *u=[NSString stringWithContentsOfFile:url encoding:NSUTF8StringEncoding error:nil]; 
     NSURL *imageURL=[NSURL URLWithString:u]; 
     NSData *image=[NSData dataWithContentsOfURL:imageURL]; 
     [image writeToFile:[pat stringByAppendingPathComponent:@"image.png"] atomically:YES]; 
     dispatch_sync(dispatch_get_main_queue(), ^{ 
      UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
      cell.imageView.image=[UIImage imageWithContentsOfFile:[pat stringByAppendingPathComponent:@"image.png"]]; 
      [cell setNeedsLayout]; 
      NSLog(@"Download"); 
     }); 
    }); 
    cell.imageView.image=[UIImage imageNamed:@"placeholder"]; 
} 
else 
{ 
    NSLog(@"cache"); 
    cell.imageView.image=[UIImage imageWithContentsOfFile:[pat stringByAppendingPathComponent:@"image.png"]]; 
} 
+0

感謝您的回覆......但是,請您提供一些示例代碼? – blackhawk4152

+0

更新了我的答案 – hypercrypt

+0

謝謝,男人!正是我想要的 – blackhawk4152

2

在您的- (void)tableView:(UITableView *)aTableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {您需要清除圖像,或將其重置爲您的微調器。由於表視圖行被重用,這就是您將看到的行爲。

2

不UITableViewCell的定義 - (無效)prepareForReuse用於這一目的? 覆蓋它並清除你的imageView。

+0

根據[文檔](http://developer.apple.com/library/ios/#documentation/uikit/reference/UITableViewCell_Class/Reference/Reference.html#//apple_ref/occ/instm/UITableViewCell/prepareForReuse)你不應該觸及prepareForReuse內的內容。您應該重置cellForRowAtIndexPath中的內容。 –