如何才能超级成为NSTimer的目标?

时间:2012-07-06 20:22:36

标签: objective-c ios nstimer

我正在尝试使用NSTimer来调用类的超类中的函数。

如果我这样称呼它,该功能就可以了:

[super playNarrationForPage:[NSNumber numberWithInt:1]];

但如果我这样做:

NSTimer *narrationTimer = [NSTimer scheduledTimerWithTimeInterval:7.5
                                                           target:self.superclass
                                                           selector:@selector(playNarrationForPage:) 
                                                           userInfo:[NSNumber numberWithInt:1] 
                                                           repeats:NO
                          ];

我收到此错误:unrecognized selector sent to class 0x106890 2012-07-06 21:14:59.522 MyApp[19955:707] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[MyBaseClass playNarrationForPage:]: unrecognized selector sent to class 0x106890'

我尝试将super设置为target:,但我被告知“使用未声明的标识符超级”。有什么想法吗?

3 个答案:

答案 0 :(得分:9)

由于self.superclass会返回Class个对象,因此绝对不是您想要的。

此外,您似乎并不了解NSTimer如何调用其目标。您使用NSNumber作为计时器的userInfo,而您的playNarrationForPage:方法似乎需要NSNumber个参数。但NSTimer在调用目标时,会将其userInfo作为参数传递! NSTimer传递本身作为参数,如下所示:

// self is the NSTimer object here!
[self.target performSelector:self.selector withObject:self];

必须为您的计时器创建一个新方法。这个新方法需要以计时器作为参数,如下所示:

- (void)narrationTimerDidFire:(NSTimer *)timer {
    [self playNarrationForPage:timer.userInfo];
}

然后,您需要在创建计时器时使用该选择器:

NSTimer *narrationTimer = [NSTimer scheduledTimerWithTimeInterval:7.5
    target:self
    selector:@selector(narrationTimerDidFire:)
    userInfo:[NSNumber numberWithInt:1]
    repeats:NO];

如果你真的想让narrationTimerDidFire:调用[super playNarrationForPage:],编译器会告诉你。但这样做非常可疑。如果您没有在子类中重写playNarrationForPage:,则没有理由直接引用super;你的子类继承了它的超类的playNarrationForPage:方法。如果在您的子类中覆盖playNarrationForPage:,那么从计时器的回调中绕过它会表明您的设计出现了问题。

答案 1 :(得分:5)

时间你应该使用super,当你在一个方法中并想要调用超类的实现相同的方法时(包括间接 - - 见下文)。

self.superclass作为计时器的目标是没有意义的,除非你的目标是在超类上调用类方法。

只需使用self作为目标。如果这不起作用,因为你重写playNarrationForPage:并想要将调用延迟到super,那么创建一个单独的方法,它可以执行以下操作:

- (void) _delayedDoIt
{
     [super playNarrationForPage:1];
}

并通过计时器从playNarrationForPage:的自我实现中调用它。

答案 2 :(得分:4)

您无法直接告诉它调用super方法。 target只是指向对象的指针,super没有来自self实例的单独指针地址。

同时通过将target分配给self.superclass,您告诉target是该类。因此,您尝试调用类方法而不是实例方法,这不是您想要做的。

执行此操作的唯一方法是将目标分配给self并使用单独的方法,例如:

- (void)callSuperMethod
{
    [super playNarrationForPage:[NSNumber numberWithInt:1]];
}