我正在尝试使用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:
,但我被告知“使用未声明的标识符超级”。有什么想法吗?
答案 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]];
}