NSTimer在我第一次告诉它时停止,然后拒绝停止

时间:2011-01-27 16:04:46

标签: iphone ios nstimer

我在NSTimer标题中声明了UIViewController

NSTimer *mainTimer;

我在实现中的viewWillAppear方法中启动它,所以:

mainTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateAll) userInfo:nil repeats:YES];

我有一个按钮,用于翻转名为showInfo的(标准实用程序应用模板)视图,它具有以下命令:

[mainTimer invalidate];

当我的应用程序启动时,计时器启动并完成它。第一次点击该按钮并且视图翻转时,计时器停止。当我完成flipSideViewController并且主视图重新出现时,计时器再次启动。到目前为止,好。问题是随后按下按钮(因此调用[mainTimer invalidate]不会使定时器停止。它只是继续前进。我可以来回翻转我想要的所有内容并继续更新。对于笑话,我把连续两次invalidate次调用,但崩溃了。

更新:

发现问题。从flipSideViewController返回后,我自己正在调用viewWillAppear,这将创建计时器。运行循环也会自动调用viewWillAppear,因此创建了第二个计时器。这只发生在我访问翻转侧后,所以当我第一次翻转时,计时器(单个实例)会正常停止。奇怪的是我可以创建两个同名的计时器......

4 个答案:

答案 0 :(得分:3)

一旦计时器失效,它将永远不会再次发射。

因此,如果“计时器继续”,那么它是一个不同的计时器。确保您正在与您认为自己的实例对话。我已经看到了很多错误,其中开发人员分配/初始化一个实例,然后加载一个NIB并导致一个特定类的不同实例发挥作用。我可以在这里看到类似的事情。

请注意,在作为计时器目标的对象的dealloc中无法使计时器无效。计时器将保留目标,因此,目标无法在计时器中首先被无效[正确]解除分配。

答案 1 :(得分:2)

我做的完全相同,似乎对我有用。我在xcode模板中做了什么:

转到MainViewController.h并输入:

@interface MainViewController : UIViewController <FlipsideViewControllerDelegate> {
    NSTimer* timer;
}

@property (nonatomic, retain) NSTimer* timer;

- (IBAction)showInfo:(id)sender;

@end

转到MainViewController.m并添加:

@synthesize timer;

-(void) viewWillAppear:(BOOL)animated {
    NSLog(@"Timer!");
    timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateAll) userInfo:nil repeats:YES];
}

-(void) updateAll {
    NSLog(@"run");
}

- (IBAction)showInfo:(id)sender {    
    [timer invalidate];
    FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:@"FlipsideView" bundle:nil];
    controller.delegate = self;

    controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    [self presentModalViewController:controller animated:YES];

    [controller release];
}

就是这样,它对我来说运行良好。这会有所帮助吗?也许你的问题出在其他地方 - 你在updateAll做了什么?

答案 2 :(得分:1)

来自[NSTimer invalidate]的文档:

  

阻止接收器射击   再次请求将其删除   它的运行循环。

所以我会调用invalidate然后释放你的计时器。它看起来并不像你首先保留在计时器上。因此,在制作时保留计时器,在需要时使计时器无效,然后在无效之后释放。

下一个viewWillAppear,确保你正在制作并保留一个新的计时器。

答案 3 :(得分:1)

可能会多次调用viewWillAppear。

在创建计时器之前,您应该确保计时器无效

[mainTimer invalidate];
mainTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateAll) userInfo:nil repeats:YES];

当然,如果您在某个其他地方也使计时器无效,则应将其指定为空。

[mainTimer invalidate];
mainTimer = NULL;