无论数据来自何处,为了保持滚动顺畅,您需要在单独的线程上获取数据,并且仅当内存中有数据时才更新 UI。Grand Central Despatch是必经之路。这是一个框架,假设您有一个self.photos
字典,其中包含对图像文件的文本引用。图像缩略图可能会或可能不会加载到实时字典中;可能在也可能不在文件系统缓存中;否则从在线商店获取。它可以使用 Core Data,但平滑滚动的关键是您无需等待数据来自任何地方。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Photo Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//identify the data you are after
id photo = [self.photos objectAtIndex:indexPath.row];
// Configure the cell based on photo id
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//move to an asynchronous thread to fetch your image data
UIImage* thumbnail = //get thumbnail from photo id dictionary (fastest)
if (!thumbnail) { //if it's not in the dictionary
thumbnail = //get it from the cache (slower)
// update the dictionary
if (!thumbnail) { //if it's not in the cache
thumbnail = //fetch it from the (online?) database (slowest)
// update cache and dictionary
}
}
}
if (thumbnail) {
dispatch_async(dispatch_get_main_queue(), ^{
//return to the main thread to update the UI
if ([[tableView indexPathsForVisibleRows] containsObject:indexPath]) {
//check that the relevant data is still required
UITableViewCell * correctCell = [self.tableView cellForRowAtIndexPath:indexPath];
//get the correct cell (it might have changed)
[[correctCell imageView] setImage:thumbnail];
[correctCell setNeedsLayout];
}
});
}
});
return cell;
}
如果您使用某种单例图像存储管理器,您会期望管理器处理缓存/数据库访问的细节,这简化了这个示例。
这部分
UIImage* thumbnail = //get thumbnail from photo id dictionary (fastest)
if (!thumbnail) { //if it's not in the dictionary
thumbnail = //get it from the cache (slower)
// update the dictionary
if (!thumbnail) { //if it's not in the cache
thumbnail = //fetch it from the (online?) database (slowest)
// update cache and dictionary
}
}
将被替换为
UIImage* thumbnail = [[ImageManager singleton] getImage];
(您不会使用完成块,因为当您返回主队列时,您实际上是在 GCD 中提供了一个完成块)