NSTimer 导致崩溃

Posted

技术标签:

【中文标题】NSTimer 导致崩溃【英文标题】:NSTimer causes crash 【发布时间】:2012-05-04 08:13:11 【问题描述】:

以下方法会导致崩溃。 UI 就像一个按钮,它处理 NSTimer 的启动/停止功能。如果计时器运行,则更新 UILabel。使用 viewDidLoad 方法使我的计时器工作,停止它也工作,但再次启动它会使应用程序崩溃。

删除 viewDidLoad 方法中的 alloc 并尝试使用开始按钮会导致崩溃立即。甚至 NSLog(@"Start now"); 也没有被调用。

代码:

- (void)tick 
NSLog(@"tick");
float value = [moneyLabel.text floatValue];
moneyLabel.text = [NSString stringWithFormat:@"%f", value + 1.0];



- (IBAction)startStopButtonClicked:(UIButton *)sender 
if ([sender.titleLabel.text isEqualToString:@"Start"]) 
    NSLog(@"Start now");
    if (timer) 
        NSLog(@"Timer valid");
        [timer fire];
     else 
        NSLog(@"Timer is nil");
        timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(tick) userInfo:nil repeats:YES];
        [timer fire];
    

    NSLog(@"bla");

    [sender setTitle:@"Stop" forState:UIControlStateNormal];
 else 
    [timer invalidate];
    timer = nil;
    NSLog(@"Stopped.");
    NSLog(@"Timer isValid: %@", timer);
    [sender setTitle:@"Start" forState:UIControlStateNormal];


【问题讨论】:

是的,请发布您的崩溃日志,以便我们为您提供帮助... *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[__NSCFArray startStopButtonClicked:]:无法识别的选择器发送到实例 0x683d8e0” 【参考方案1】:

我认为根本不需要打电话给[NSTimer fire];应该足以让计时器决定何时触发。

首先确保timernil(如果它是对象的实例变量则应该是),尽管在- (id)init 中将其显式设置为nil 不会有任何影响。

接下来我将使用计时器本身的状态来确定是否按下了启动/停止,而不是按钮中的文本:

- (IBAction)startStopButtonClicked:(UIButton *)sender

    if (timer != nil)
    
        NSLog(@"Stopping timer");
        [timer invalidate];
        timer = nil;
    
    else
    
        NSLog(@"Starting timer");
        timer = [NSTimer scheduledTimerWithTimeInterval:1
                                                 target:self
                                               selector:@selector(tick)
                                               userInfo:nil
                                                repeats:YES];
    

    [sender setTitle:(timer != nil ? @"Stop" : @"Start")
            forState:UIControlStateNormal];

【讨论】:

*** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[__NSCFArray startStopButtonClicked:]:无法识别的选择器发送到实例 0x683d8e0” @Darwin 这看起来像是您发布的代码之外的崩溃。鉴于另一个答案似乎表明此代码有效,看来您找错地方了。 在我的项目中除了这个之外没有其他代码......其他一切都像 viewDidLoad 一样是标准的。真是一团糟……【参考方案2】:

您发布的代码可以正常工作 - 刚刚在一个新项目中对其进行了测试,因此问题可能出在其他地方。我只通过声明 ivar NSTimer *timer; 而不在 viewDidLoad: 或指定的初始化程序中进行任何初始化来测试它...

【讨论】:

问题是没有在 AppDelegate 中添加 rootViewController。 WTF。

以上是关于NSTimer 导致崩溃的主要内容,如果未能解决你的问题,请参考以下文章

UITableView 单元重用导致 NSTimer 问题

重复 NSTimer 会导致在第一个动画上截断 animateWithDuration

NSTimer - 适用于 iOS 10 但不适用于 iOS 9.3

NSTimer 不适用于 AsyncSocket 库

在 Swift 中使用 NSTimer 时发送到类的无法识别的选择器; NSInvalidArgumentException

解决NSTimer或CADisplayLink计时器造成的循环引用问题。