NSTimer不会停止

时间:2014-01-20 12:36:10

标签: ios iphone objective-c 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;
}

我在Timer中启动HomeViewController即使我无效,它仍然在OtherViewController中运行。我的代码出了什么问题?

5 个答案:

答案 0 :(得分:12)

首先,当您覆盖生命周期方法时,应该包含对该方法的super版本的调用。

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

第三,在iOS 6.0中,viewDidUnload 已弃用,此时不应该使用它,除非您不再支持向后兼容性。它永远不会在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?”

答案 1 :(得分:1)

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

答案 2 :(得分:1)

    [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;
}

答案 3 :(得分:0)

无需在主运行循环上添加计时器(再次)。或者您是否有必要在commonModes中运行它?对我来说,这绝不是必要的。

来自NSTimer Documentation

  

scheduledTimerWithTimeInterval:调用:重复:

     

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

由于NSRunLoop Documentation指出你可以在几种运行循环模式下添加计时器,可能这就是问题所在。

  

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");

}

希望这有帮助。

答案 4 :(得分:-3)

-(void)viewDidUnload是一个代理,仅在内存警告时触发,在iOS 6之后不推荐使用。它也永远不会在模拟器上触发。

停止计时器

- (void)viewWillDisappear:(BOOL)animated

- (void)viewDidDisappear:(BOOL)animated