我有一个UIView,里面有一个UITableView和一个UIImageView。UITableView占据了UIView的上半部分。UIImageView占据了UIView的下半部分。
我正在使用NSTimer来更新在UIImageView中显示的图像。基本上,每隔3秒,UIImageView就会加载一个新的UIImage。
问题是,如果我从UITableView中选择一行,NSTimer将继续运行。如何在didSelectRowFromIndexPath上停止NSTimer,然后在视图返回屏幕时重新启动它?
-(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];
}发布于 2011-05-03 06:12:27
保留对您创建的计时器的引用,以便您可以在需要时停止它。下次你需要它的时候,你可以创建一个新的计时器。听起来最好的地方是viewDidAppear:和viewWillDisappear:。我不知道你为什么要在一个新线程上启动计时器。你可能有一个很好的理由这样做,但我从来没有需要这样做。
//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;
}发布于 2011-05-03 06:02:06
您可以使用NSTimer的invalidate方法来销毁计时器。
然后,当您返回到视图时,必须重新创建它,就像在startTimerThread方法中所做的那样。
发布于 2011-05-03 06:06:31
若要从startTimerThread方法外部访问线程,应向类添加一个属性。我建议使用property而不是ivar,因为你可以自动合成原子访问器。如何处理计时器取决于是暂停还是停止计时器。
停止计时器意味着下一次启动计时器时,计时器将在剩下整整3秒的时间内启动。这意味着,如果计时器在你停止计时器时在1秒内触发,那么在你再次启动它后,它仍然需要3秒才能启动。然而,停止非常简单。stopTimerThread的定义如下:
- (void)stopTimerThread {
NSTimer *theTimer = self.timer;
[theTimer invalidate];
self.timer = nil;
}由于另一个线程中的运行循环现在没有源代码,它将自动退出,线程也将结束,因此当您想要再次启动它时,可以使用startTimerThread。
暂停计时器意味着,如果你暂停计时器时,它将在1秒内触发,那么它将在你重新启动它后1秒内触发。为此,您还需要一个包含计时器触发前剩余时间的属性,该属性将在stopTimerThread中设置并在startTimerThread中使用。stopTimerThread的实现如下:
- (void)stopTimerThread {
NSTimer *theTimer = self.timer;
NSDate *fireDate = [theTimer fireDate];
[theTimer invalidate];
self.timerTimeRemaining = - [fireDate timeIntervalSinceNow];
self.timer = nil;
}请注意,剩余时间被设置为时间间隔的负数,因为触发日期将在现在之前。您还必须修改startTimerThread,以便在设置计时器时将剩余时间考虑在内。
- (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
}https://stackoverflow.com/questions/5862743
复制相似问题