使用NSTimer传递原始参数的正确方法

Mar*_*ark 2 cocoa cocoa-touch objective-c nstimer

我正在使用一个调用此方法的基本计时器:

- (void) refresh:(id)obj
{
    if (obj == YES) doSomething;
}
Run Code Online (Sandbox Code Playgroud)

我想从我的代码的某些区域以及计时器中调用此方法

[NSTimer scheduledTimerWithTimeInterval:refreshInterval
                            target:self
                            selector:@selector(refresh:) 
                            userInfo:nil 
                            repeats:YES];
Run Code Online (Sandbox Code Playgroud)

当我YES作为参数的userInfo参数时,我得到一个EXC_BAD_ACCESS错误; 为什么是这样?

有人可以帮助我以正确的方式做到这一点,以便没有丑陋的铸造等吗?

kpe*_*yua 10

所述userInfo参数必须是一个对象; 它是打字的id.YES是原始的,即价值1.为了确保userInfo对象没有被释放,计时器保留它.所以,当你通过时YES,NSTimer正在做[(id)YES retain].在您自己的代码中尝试,看看会发生什么.:-P

正如文档所述,您为方法指定的选择器必须具有签名

- (void)timerFireMethod:(NSTimer*)theTimer
Run Code Online (Sandbox Code Playgroud)

这意味着您不能让NSTimer只调用任何方法 - 至少不是直接调用.您可以使用上述签名创建一个特殊方法,然后调用您想要的任何方法.

所以,假设你有一个叫做的方法refresh:,你想要经常调用它,传递它YES.你可以这样做:

// somewhere
{
    [NSTimer scheduledTimerWithTimeInterval:refreshInterval
                                     target:self
                                   selector:@selector(invokeRefresh:)
                                   userInfo:nil
                                    repeats:YES];
}

- (void)invokeRefresh:(NSTimer *)timer {
    [self refresh:YES];
}

- (void)refresh:(BOOL)flag {
    if (flag) {
        // do something
    }
}
Run Code Online (Sandbox Code Playgroud)