无法访问NSTimer的userInfo

Mda*_*daG 0 objective-c nstimer automatic-ref-counting ios7

我有这个代码。

- (void)scheduleTimerAfterDelay:(NSTimeInterval)delay {
    dispatch_async(dispatch_get_main_queue(), ^{
        _timer = [NSTimer scheduledTimerWithTimeInterval:delay
                                                  target:self
                                                selector:@selector(triggerTimer:)
                                                userInfo:[NSString stringWithFormat:@"%f", delay]
                                                 repeats:NO];
    });
}

- (void)triggerTimer:(NSTimer *)timer {
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"Triggered timer after %@ s.", _timer.userInfo); // <-- Exception thrown!
        // Do stuff
    });
}
Run Code Online (Sandbox Code Playgroud)

但是,当计时器触发时,_timer.userInfo会导致Exception: EXC_BAD_ACCESS (code=1, address=0xc))

我在这里错过了什么?在异常行的断点处打印_timer表示_timer为<__NSCFTimer: 0x14ec8cb0>。但是我也无法通过lldb访问userInfo。我正在使用ARC。

tro*_*foe 5

userInfo应该是一本字典:

_timer = [NSTimer scheduledTimerWithTimeInterval:delay
                                          target:self
                                        selector:@selector(triggerTimer:)
                                        userInfo:@{ @"name" : @"Zinedine Zidane",
                                                    @"age"  : @42 }
                                         repeats:NO];
Run Code Online (Sandbox Code Playgroud)

并且显然您需要在选择器中更改访问它的方式:

您需要userInfo在致电之前保留dispatch_async()

- (void)triggerTimer:(NSTimer *)timer {
    NSString *s = timer.userInfo;    // Strong reference!
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"Triggered timer after %@ s.", s);
        // Do stuff
    });
}
Run Code Online (Sandbox Code Playgroud)

  • 这里的问题是,Timer在mainThread上触发“ triggerTimer”,并且您再次要求在maintherad上进行调度。因此,将在下一个runLoop上完成调度的工作。但是计时器对象仅对此Runloop有效。 (2认同)