NSTimer不会停止


[self performSelectorInBackground:@selector(method) withObject:nil];
-(void)method 
{
timer1 = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(getLastImageName1) userInfo:nil repeats:YES];
runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:timer1 forMode:NSRunLoopCommonModes];
[runLoop run];
}
-(void)viewdidunload
{
[timer1 invalidate];
timer1=nil;
}

我开始TimerHomeViewController即使我无效,它也一直在OtherViewController运行.我的代码有什么问题?

首先,在重写生命周期方法时,应包括对该方法super版本的调用。

其次,Objective-C 区分大小写,所以即使你的应用程序尝试调用生命周期,即使viewDidUnload,你的方法也永远不会被调用,因为这就是你对方法的命名。

第三,viewDidUnload在iOS 6.0中已被弃用,除非你要不遗余力地支持向后兼容性,否则此时根本不应该使用。 它永远不会在iOS 6.0及更高版本中调用。


如果您希望计时器在用户离开当前视图时停止,则需要如下所示的内容:

- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
if (timer1.isValid) {
[timer1 invalidate];
}
timer1 = nil;
}

如果你正在寻找别的东西,你需要详细说明你想要完成什么。


如果您正在处理iOS 6.0之前的项目,无论出于何种原因,您的方法未被调用的原因至少部分是因为它拼写错误。 同样,Objective-C区分大小写。 您的方法名称应拼写为viewDidUnload


为了将来参考,问题不应该是"为什么我的计时器没有失效? 您应该首先使用断点或 NSLog 语句来确定您的方法viewdidunload是否尝试使计时器无效甚至触发。 当你发现它没有被调用时,请搜索以询问"为什么不调用viewdidunload? 然后你会去解决大写问题,问题(可能)仍然存在,所以做更多的研究。 如果最后,你仍然无法弄清楚,作为最坏的情况,帖子问题应该是"为什么不调用viewdidunload?

timer1 = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(getLastImageName1:) userInfo:nil repeats:YES]; 

在选择器中为函数设置冒号

-(void) getLastImageName1 :(NSTimer*)timer1
{
//Do your all process and invalidate after completion
[timer1 invalidate];
}

或者,如果您想在移动到下一个视图控制器后删除计时器,请使用@nhgrif提到的方式

- (void)viewDidDisappear:(BOOL)animated
{
[timer1 invalidate];
}
[self performSelector:@selector(method) withObject:nil afterDelay:0.0];
-(void)method
{
timer1 = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(getLastImageName1) userInfo:nil repeats:YES];
runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:timer1 forMode:NSRunLoopCommonModes];
[runLoop run];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[timer1 invalidate];
timer1=nil;
}

无需在主运行循环上(再次)添加计时器。还是您也有必要在通用模式下运行它?对我来说,这从来都没有必要。

来自 NSTimer 文档:

scheduledTimerWithTimeInterval:invocation:repeats:

创建并返回一个新的 NSTimer 对象,并在 默认模式下的当前运行循环。

由于 NSRunLoop 文档指出您可以在多种运行循环模式下添加计时器,因此也许这就是问题所在。

addTimer:forMode:

讨论 您可以将计时器添加到多个输入模式。跑步时 在指定模式下,接收器使计时器触发或 在其预定的火灾日期之后。触发时,计时器调用其 关联的处理程序例程,它是指定选项上的选择器 对象。

我也不明白你为什么要用 performSelector 调用计时器创建? 我刚刚写了一个简约的样本。这完全有效!

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(doWork:) userInfo:Nil repeats:YES];
}
- (void)viewDidDisappear:(BOOL)animated{
[self.timer invalidate];
[super viewDidDisappear:animated];
}
- (void) doWork:(id) userInfo
{
NSLog(@"Working again");
}

希望这有帮助。

-(void)viewDidUnload是一个委托,仅在内存警告时触发,并在iOS 6之后被弃用。它也永远不会在模拟器上触发。

停止定时器

- (void)viewWillDisappear:(BOOL)animated

或在

- (void)viewDidDisappear:(BOOL)animated

最新更新