Ste*_*ven 6 iphone objective-c uitableview grand-central-dispatch ios
我有一个UITableView使用GCD将URL中的图像异步加载到单元格中.问题是如果用户轻弹超过150行,150个操作排队并执行.我想要的是取消/取消那些过去和离开屏幕的人.
我该怎么做呢?
我的代码(非常标准):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
// after getting the cell...
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
if (runQ) {
NSString *galleryTinyImageUrl = [[self.smapi getImageUrls:imageId imageKey:imageKey] objectForKey:@"TinyURL"];
NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:galleryTinyImageUrl]];
dispatch_async(dispatch_get_main_queue(), ^{
if (imageData != nil) {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.imageView.image = [UIImage imageWithData:imageData];
}
});
}
});
Run Code Online (Sandbox Code Playgroud)
runQ是BOOL我设置为NOon 的ivar viewWillDisappear,它(我认为)具有在UITableView弹出导航控制器时快速刷新队列的效果.
那么,回到我原来的问题:如何取消已经关闭屏幕的单元格的图像获取操作?谢谢.
首先,不要在滚动时排队操作.相反,只viewDidLoad在用户停止滚动时和当用户停止滚动时加载图像:
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
for (NSIndexPath *indexPath in [self.tableView indexPathsForVisibleRows]) {
[self loadImageForCellAtPath:indexPath];
}
}
Run Code Online (Sandbox Code Playgroud)
如果您仍希望能够取消对隐形单元格的加载,则可以使用NSBlockOperation而不是GCD:
self.operationQueue = [[[NSOperationQueue alloc] init] autorelease];
[self.operationQueue setMaxConcurrentOperationCount:NSOperationQueueDefaultMaxConcurrentOperationCount];
// ...
-(void)loadImageForCellAtPath:(NSIndexPath *)indexPath {
__block NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
if (![operation isCancelled]) {
NSString *galleryTinyImageUrl = [[self.smapi getImageUrls:imageId imageKey:imageKey] objectForKey:@"TinyURL"];
NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:galleryTinyImageUrl]];
dispatch_async(dispatch_get_main_queue(), ^{
if (imageData != nil) {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.imageView.image = [UIImage imageWithData:imageData];
}
});
}
}];
NSValue *nonRetainedOperation = [NSValue valueWithNonretainedObjectValue:operation];
[self.operations addObject:nonRetainedOperation forKey:indexPath];
[self.operationQueue addOperation:operation];
}
Run Code Online (Sandbox Code Playgroud)
这operations是一个NSMutableDictionary.如果要取消操作,请按单元格检索indexPath,取消它,然后将其从字典中删除:
NSValue *operationHolder = [self.operations objectForKey:indexPath];
NSOperation *operation = [operationHolder nonretainedObjectValue];
[operation cancel];
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2074 次 |
| 最近记录: |