UIImageView 셀의 UITableView를 구현합니다. 각 셀은 NSTimer를 통해 주기적으로 5 초마다 새로 고칩니다. 각 이미지는 백그라운드 스레드의 서버에서로드되고 해당 백그라운드 스레드에서 performSelectorOnMainThread
을 호출하여 UI를 업데이트하고 새 이미지를 표시합니다. 여태까지는 그런대로 잘됐다.iOS : 백그라운드 스레드가 주 스레드에서 UI를 업데이트하지 못하게하는 방법은 무엇입니까?
현재 이미지가 현재 셀에로드 될 때까지 기다리지 않고 새로운 셀로 빠르게 스크롤 할 때 문제가 발생합니다. 그러나 새 셀에는 새 셀 대신 이전 셀의 이미지가 표시됩니다. NSTimer의 다음 라운드가 이미지를 올바르게 표시하지만 사용자가 처음에는 혼란 스러울 수 있습니다.
UITableView의 셀을 다시 사용하지 않으면 문제가 사라지지만 내 응용 프로그램에 표시 할 셀의 수를 감안할 때이 옵션이 아닙니다.
그래서 내가 생각할 수있는 유일한 해결책은 사용자가 스크롤 작업을 수행한다는 것을 알고있는 경우 오래된 이미지를 표시 할 백그라운드 스레드를 취소 (또는 중지)하는 것입니다.
이 방법이 모범 사례가 아니므로 조언을 구하는 것이 바람직합니다.
// 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) {
}];
}
WWDC 2012 세션 211은 대기열 취소, 최적화 등의 다양한 수준으로이를 자세히 설명합니다. 멋진 동영상입니다. 'cellForRow'에 – jrturton
이 있습니다. 이미지가 없으면 이미지를 nil로 설정하는 것이 어떻습니까? 그런 식으로, 그것은 틀린 심상 대신 일시적으로 공백 일 것이다. – user102008
@ user102008 그랬지만 작동하지 않습니다. 잘못된 이미지가 메인 스레드에 이미 대기 중입니다 ('새로 고침'이 실행 중간에 있음). 표시 대기 중입니다. –