暂停 NSTimer
我有一个 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];
}
I have a UIView
with a UITableView
and a UIImageView
in it. The UITableView
takes up the top half of the UIView
. The UIImageView
takes the bottom half of the UIView
.
I am using an NSTimer
to update the image that is being displayed in the UIImageView
. Basically, every 3 seconds, the UIImageView
loads in a new UIImage
.
Problem is, if I select a row from the UITableView
, the NSTimer
keeps running. How can I stop the NSTimer
on didSelectRowFromIndexPath
, and then start it again when the view returns to the screen?
-(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];
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
保留对您创建的计时器的引用,以便您可以在需要时停止它。下次您需要它时,您只需创建一个新计时器即可。听起来您执行此操作的最佳位置是 viewDidAppear: 和 viewWillDisappear: 。我不确定你为什么要在新线程上启动计时器。你可能有充分的理由这样做,但我从来不需要这样做。
Keep a reference to the timer you create so you can stop it when needed. The next time you need it you can just create a new timer. It sounds like the best places for you to do this are in viewDidAppear: and viewWillDisappear:. I'm not sure why you are starting the timer on a new thread. You may have a good reasons for doing so but I have never needed to do this.
您可以使用 NSTimer 的
invalidate
方法来销毁计时器。然后,当您返回视图时,您必须重新创建它,就像在
startTimerThread
方法中所做的那样。You can use the NSTimer's
invalidate
method to destroy the timer.You'll then have to recreate it, as you did in your
startTimerThread
method, when you return to the view.要从
startTimerThread
方法外部访问线程,您应该向您的类添加一个属性。我建议使用属性而不是 ivar,因为你可以自动合成原子访问器。您对计时器的操作取决于您是要暂停还是停止它。停止计时器意味着下次启动计时器时,计时器将在还剩 3 秒时开始。这意味着如果计时器在您停止时会在 1 秒内触发,那么在您再次启动后仍需要 3 秒才能触发。然而,停止是非常简单的。
stopTimerThread
的定义如下:由于您的另一个线程中的 runloop 现在没有源,它会自动退出并且线程将结束,因此您可以在以下情况下使用
startTimerThread
你想重新开始。暂停定时器意味着,如果暂停时它会在 1 秒内触发,那么在您重新启动定时器后,它会在 1 秒内触发。为此,您还需要一个包含计时器触发前剩余时间的属性,该属性将在
stopTimerThread
中设置并在startTimerThread
中使用。stopTimerThread
的实现如下:请注意,剩余时间设置为时间间隔的负数,因为触发日期将在现在之前。您还必须修改
startTimerThread
以在设置计时器时考虑剩余时间。To get access to the thread from outside the
startTimerThread
method, you should add a property to your class. I would suggest property over ivar because you can have atomic accessors synthesized automatically. What you do with the timer depends on whether you want to pause or stop it.Stopping the timer means the next time you start it, it will start with the full 3 seconds remaining. This means if the timer will fire in 1 second when you stop it, it will still take 3 seconds to fire after you start it again. However, stopping is very simple. A
stopTimerThread
would be defined as follows:Since the runloop in your other thread now has no sources, it will automatically exit and the thread will end, so you can use
startTimerThread
when you want to start it again.Pausing the timer means that, if it will fire in 1 second when you pause it, it will fire 1 second after you restart it. To do this, you will also need a property containing the time remaining before the timer fires, which will be set in
stopTimerThread
and used instartTimerThread
. The implementation ofstopTimerThread
is as follows:Notice that the time remaining is set to be the negative of the time interval, since the fire date will be before now. You will also have to modify
startTimerThread
to take the time remaining into account when setting up the timer.创建一个标志(BOOL)来控制图像的更新。
当您希望更新图像的例程忽略它是由计时器事件触发调用的事实时,请清除它。当您希望恢复图像更新时,只需设置该标志即可。也许是这样的:
由于您每三秒才触发一个方法,因此让计时器运行并不是什么大问题。
您可以做的另一件事是设置计时器,使其不重复。完成此操作后,可以在代码中的其他位置做出重新启用计时器的决定,而不是自动做出。您甚至可以在回调函数中执行此操作,并且如果您愿意,仍然可以使用“image_updates_enabled”标志。
Create a flag (BOOL) to control the updating of the image.
Clear it when you want the routine that updates the image to ignore the fact that it was called by the timer event firing. When you want the image updates to resume, just set the flag. Maybe something like this:
Since you are firing a method only every three seconds it isn't a big deal to just let the timer run.
The other thing you can to is to setup the timer so that it does not repeat. With that in place the decision to re-enable the timer could be made somewhere else in your code rather than automatically. You could even do it within the callback function and still use the "image_updates_enabled" flag if you wish.