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) {
}];
}