3 回答

TA貢獻1827條經驗 獲得超4個贊
這里的問題是您的圖像獲取塊正在保存對tableview單元的引用。下載完成后,imageView.image即使您回收了單元格以顯示其他行,它也會設置屬性。
在設置映像之前,您需要下載完成塊來測試映像是否仍與單元格相關。
還需要注意的是,您不會將圖像存儲在單元格中以外的任何位置,因此,每次在屏幕上滾動一行時,您都將再次下載它們。您可能希望將它們緩存在某個位置,并在開始下載之前查找本地緩存的圖像。
編輯:這是使用單元格的tag屬性進行測試的簡單方法:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.tag = indexPath.row;
NSDictionary *parsedData = self.loader.parsedData[indexPath.row];
if (parsedData)
{
cell.imageView.image = nil;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^(void) {
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:parsedData[@"imageLR"]];
UIImage* image = [[UIImage alloc] initWithData:imageData];
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
if (cell.tag == indexPath.row) {
cell.imageView.image = image;
[cell setNeedsLayout];
}
});
}
});
cell.textLabel.text = parsedData[@"id"];
}
return cell;
}

TA貢獻1993條經驗 獲得超6個贊
關鍵是您沒有完全了解單元重用概念。這與異步下載不太吻合。
塊
^{
cell.imageView.image = image;
[cell setNeedsLayout];
}
在請求完成并且所有數據都已加載時被執行。但是,在創建塊時,單元會獲得其值。
到執行塊時,單元仍指向現有單元之一。但是用戶很有可能繼續滾動。同時,該單元格對象已被重新使用,并且該圖像與“ 舊 ”單元格相關聯,該單元格已被重用,分配和顯示。之后不久,除非用戶進一步滾動,否則將加載并分配并顯示正確的圖像。等等等等。
您應該尋找一種更聰明的方法。有很多花絮。Google用于延遲加載圖片。

TA貢獻1719條經驗 獲得超6個贊
使用索引路徑獲取單元格。如果看不到該單元格nil,則不會有問題。當然,您可能希望在下載數據時緩存數據,以便在已有圖像后立即設置單元格的圖像。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (self.loader.parsedData[indexPath.row] != nil)
{
cell.imageView.image = nil;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^(void) {
// You may want to cache this explicitly instead of reloading every time.
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[self.loader.parsedData[indexPath.row] objectForKey:@"imageLR"]]];
UIImage* image = [[UIImage alloc] initWithData:imageData];
dispatch_async(dispatch_get_main_queue(), ^{
// Capture the indexPath variable, not the cell variable, and use that
UITableViewCell *blockCell = [tableView cellForRowAtIndexPath:indexPath];
blockCell.imageView.image = image;
[blockCell setNeedsLayout];
});
});
cell.textLabel.text = [self.loader.parsedData[indexPath.row] objectForKey:@"id"];
}
return cell;
}
- 3 回答
- 0 關注
- 556 瀏覽
添加回答
舉報