5

我实现了一个UITableView单元UIImageView格,每个单元格每 5 秒通过NSTimer. 每个图像都是从后台线程中的服务器加载的,并且从该后台线程我还更新 UI,显示新图像,方法是调用performSelectorOnMainThread. 到目前为止,一切都很好。

我注意到的问题是线程数量随着时间的推移而增加,并且 UI 变得无响应。NSTimer因此,如果单元格离开屏幕,我想使之无效。我应该使用哪些委托方法UITableView来有效地做到这一点?

我将 anNSTimer与每个单元格相关联的原因是我不希望所有单元格同时发生图像转换。顺便说一句,还有其他方法可以做到这一点吗?例如,是否可以只使用一个NSTimer

(我不能使用SDWebImage,因为我的要求是在从服务器加载的循环中显示一组图像)

// 在 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];
    }
}  

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

2 回答 2

6

willMoveToSuperview:和/或didMoveToSuperview:不适用于 ios 6.0

从 ios 6.0 你有以下 UITableViewDelegate 方法

- (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

使用此方法检测何时从表格视图中删除单元格,而不是监视视图本身以查看它何时出现或消失。

于 2013-09-17T09:09:18.553 回答
5

If you properly manage memory and dequeue reusable cells, you can subclass UITableViewCell and override its - prepareForReuse method in order to stop the timer.

Furthermore, as @lnfaziger points out, if you want to stop the timer immediately when the cell is removed from the table view, you can also override its willMoveToSuperview: and/or didMoveToSuperview: method and check if its superview parameter is nil - if it is, the cell is being removed, so you can stop the timer.

于 2012-09-03T07:50:31.430 回答