我必须从通讯录中获取联系人,如果在UITableView
.
我使用库获取所有联系人ABContactsHelper
,然后异步获取UITableView
使用 GCD 块中可见行的照片。
我提到了一个 Apple 示例代码,它等待 UITableView 完成滚动,获取 VisibleNSIndexPath
并创建线程来获取照片。到目前为止,我的问题是两个方面。
首先,如果用户滚动、停止、滚动和停止并多次滚动,则会生成太多线程来获取照片,这会降低应用程序的速度。
其次,当线程返回以在缓存中设置照片以及UITableViewCell
然而,对的引用UIImageView
现在被重用于 中的另一条记录UITableViewCell
,因此照片被放置在错误的记录上,最终被正确的记录替换,当线程为那个特定的记录回报。
这是我在停止滚动cellForRowAtIndexPath
时以及UITableView
停止滚动时使用的代码。
- (void)loadImagesLazilyForIndexPath:(NSIndexPath *)indexPath photo:(UIImageView *)photo contact:(ContactModel *)contact
{
if (!self.tableView.isDragging && !self.tableView.isDecelerating) {
UIImage *thePhoto = [self.imagesForContacts objectForKey:indexPath];
if (!thePhoto) {
// NSLog(@"Photo Not Found - Now Fetching %@", indexPath);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
@autoreleasepool {
UIImage *image = [[JMContactsManager sharedContactsManager] photoForContact:contact];
if (!image)
image = self.noProfilePhoto;
[self.imagesForContacts setObject:image forKey:indexPath];
dispatch_async(dispatch_get_main_queue(), ^{
// NSLog(@"Photo Fetched %@", indexPath);
@autoreleasepool {
NSArray *visiblePaths = [self.tableView indexPathsForVisibleRows];
BOOL visible = [visiblePaths indexOfObjectPassingTest:^BOOL(NSIndexPath * ip, NSUInteger idx, BOOL *stop) {
if (ip.row == indexPath.row && ip.section == indexPath.section) {
*stop = YES;
return 1;
}
return 0;
}];
if (visible)
photo.image = [self.imagesForContacts objectForKey:indexPath];
[[NSURLCache sharedURLCache] removeAllCachedResponses];
}
});
}
});
} else {
// NSLog(@"Photo Was Found %@", indexPath);
@autoreleasepool {
photo.image = [self.imagesForContacts objectForKey:indexPath];
}
}
}
}