我实现了 UIImageView 单元的 UITableView,每个单元通过 NSTimer 每 5 秒定期刷新一次。每个图像都是从后台线程中的服务器加载的,并且从该后台线程我还更新 UI,显示新图像,方法是调用performSelectorOnMainThread
. 到目前为止,一切都很好。
目前,当我不等到在当前单元格中加载图像并快速向下滚动到新单元格时,我遇到了一个问题。但是,该新单元格显示的是前一个单元格的图像,而不是新单元格的图像。虽然下一轮 NSTimer 会正确显示图像,但这首先会让用户感到困惑。
如果我不重用 UITableView 的单元格,问题就会消失,但考虑到要在我的应用程序中显示的单元格数量,这不是一个选项。
因此,如果我知道用户执行滚动操作,我能想到的唯一解决方案是取消(或终止)将显示旧图像的后台线程。
我想知道这可能不是最佳做法,因此,寻求您的建议。
(我也不能使用 SDWebImage,因为我的要求是在从服务器加载的循环中显示一组图像)
// In MyViewController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
NSTimer* timer=[NSTimer scheduledTimerWithTimeInterval:ANIMATION_SCHEDULED_AT_TIME_INTERVAL
target:self
selector:@selector(updateImageInBackground:)
userInfo:cell.imageView
repeats:YES];
...
}
- (void) updateImageInBackground:(NSTimer*)aTimer
{
[self performSelectorInBackground:@selector(updateImage:)
withObject:[aTimer userInfo]];
}
- (void) updateImage:(AnimatedImageView*)animatedImageView
{
@autoreleasepool {
[animatedImageView refresh];
}
}
// In AnimatedImageView.m
-(void)refresh
{
if(self.currentIndex>=self.urls.count)
self.currentIndex=0;
ASIHTTPRequest *request=[[ASIHTTPRequest alloc] initWithURL:[self.urls objectAtIndex:self.currentIndex]];
[request startSynchronous];
UIImage *image = [UIImage imageWithData:[request responseData]];
// How do I cancel this operation if I know that a user performs a scrolling action, therefore departing from this cell.
[self performSelectorOnMainThread:@selector(performTransition:)
withObject:image
waitUntilDone:YES];
}
-(void)performTransition:(UIImage*)anImage
{
[UIView transitionWithView:self duration:1.0 options:(UIViewAnimationOptionTransitionCrossDissolve | UIViewAnimationOptionAllowUserInteraction) animations:^{
self.image=anImage;
currentIndex++;
} completion:^(BOOL finished) {
}];
}