首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >暂停NSTimer

暂停NSTimer
EN

Stack Overflow用户
提问于 2011-05-03 05:34:48
回答 4查看 2.2K关注 0票数 1

我有一个UIView,里面有一个UITableView和一个UIImageViewUITableView占据了UIView的上半部分。UIImageView占据了UIView的下半部分。

我正在使用NSTimer来更新在UIImageView中显示的图像。基本上,每隔3秒,UIImageView就会加载一个新的UIImage

问题是,如果我从UITableView中选择一行,NSTimer将继续运行。如何在didSelectRowFromIndexPath上停止NSTimer,然后在视图返回屏幕时重新启动它?

代码语言:javascript
复制
-(void)viewDidLoad {
NSThread* timerThread = [[NSThread alloc] initWithTarget:self selector:@selector(startTimerThread) object:nil]; //Create a new thread
    [timerThread start]; //start the thread

} // end viewDidLoad

//
-(void) startTimerThread {
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
    [[NSTimer scheduledTimerWithTimeInterval: 3.0
                                      target: self
                                    selector: @selector(loadNextPhoto)
                                    userInfo: nil
                                     repeats: YES] retain];

    [runLoop run];
    [pool release];
}
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-05-03 06:12:27

保留对您创建的计时器的引用,以便您可以在需要时停止它。下次你需要它的时候,你可以创建一个新的计时器。听起来最好的地方是viewDidAppear:和viewWillDisappear:。我不知道你为什么要在一个新线程上启动计时器。你可能有一个很好的理由这样做,但我从来没有需要这样做。

代码语言:javascript
复制
//This code assumes you have created a retained property for loadNextPhotoTimer

    - (void)viewDidAppear:(BOOL)animated {
        [super viewDidAppear:animated];
        [self startTimer];
    }

    - (void)viewWillDisappear:(BOOL)animated {
        [super viewWillDisappear:animated];
        [self stopTimer];
    }

    - (void)startTimer {
        NSTimer *timer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:3.0] interval:3.0 target:self selector:@selector(loadNextPhoto) userInfo:nil repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
        self.loadNextPhotoTimer = timer;
        [timer release];
    }

    - (void)stopTimer {
        [self.loadNextPhotoTimer invalidate];
        self.loadNextPhotoTimer = nil;
    }
票数 2
EN

Stack Overflow用户

发布于 2011-05-03 06:02:06

您可以使用NSTimer的invalidate方法来销毁计时器。

然后,当您返回到视图时,必须重新创建它,就像在startTimerThread方法中所做的那样。

票数 1
EN

Stack Overflow用户

发布于 2011-05-03 06:06:31

若要从startTimerThread方法外部访问线程,应向类添加一个属性。我建议使用property而不是ivar,因为你可以自动合成原子访问器。如何处理计时器取决于是暂停还是停止计时器。

停止计时器意味着下一次启动计时器时,计时器将在剩下整整3秒的时间内启动。这意味着,如果计时器在你停止计时器时在1秒内触发,那么在你再次启动它后,它仍然需要3秒才能启动。然而,停止非常简单。stopTimerThread的定义如下:

代码语言:javascript
复制
- (void)stopTimerThread {
    NSTimer *theTimer = self.timer;
    [theTimer invalidate];
    self.timer = nil;
}

由于另一个线程中的运行循环现在没有源代码,它将自动退出,线程也将结束,因此当您想要再次启动它时,可以使用startTimerThread

暂停计时器意味着,如果你暂停计时器时,它将在1秒内触发,那么它将在你重新启动它后1秒内触发。为此,您还需要一个包含计时器触发前剩余时间的属性,该属性将在stopTimerThread中设置并在startTimerThread中使用。stopTimerThread的实现如下:

代码语言:javascript
复制
- (void)stopTimerThread {
    NSTimer *theTimer = self.timer;
    NSDate *fireDate = [theTimer fireDate];
    [theTimer invalidate];
    self.timerTimeRemaining = - [fireDate timeIntervalSinceNow];
    self.timer = nil;
}

请注意,剩余时间被设置为时间间隔的负数,因为触发日期将在现在之前。您还必须修改startTimerThread,以便在设置计时器时将剩余时间考虑在内。

代码语言:javascript
复制
- (void)startTimerThread {
    // set up autorelease pool, get run loop
    NSTimeInterval timeLeft = self.timerTimeRemaining;
    if(timeLeft <= 0.0) timeLeft = 3.0;
    NSDate *fireDate = [NSDate dateWithTimeIntervalSinceNow:timeLeft];
    NSTimer *theTimer = [[NSTimer alloc] initWithFireDate:fireDate interval:3.0 target:self selector:@selector(loadNextPhoto) userInfo:nil repeats:YES];
    [runLoop addTimer:theTimer forMode:NSDefaultRunLoopMode];
    self.timer = theTimer;
    [theTimer release];
    [runLoop run];
    // clean up
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5862743

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档