I'm trying to use a NSTimer
to call a function in an class's superclass.
The function works if I call it like this:
[super playNarrationForPage:[NSNumber numberWithInt:1]];
But if I do this:
NSTimer *narrationTimer = [NSTimer scheduledTimerWithTimeInterval:7.5
target:self.superclass
selector:@selector(playNarrationForPage:)
userInfo:[NSNumber numberWithInt:1]
repeats:NO
];
I get this error: 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'
I've tried setting super
as the target:
but I'm told "Use of undeclared identifier super". Any thoughts?
Since self.superclass
returns a Class
object, it's definitely not what you want.
Also, you don't seem to understand how an NSTimer
calls its target. You're using an NSNumber
as the timer's userInfo
, and your playNarrationForPage:
method seems to expect an NSNumber
argument. But an NSTimer
does not pass its userInfo
as the argument when it calls its target! The NSTimer
passes itself as the argument, like this:
// self is the NSTimer object here!
[self.target performSelector:self.selector withObject:self];
You must create a new method for your timer to call. This new method needs to take the timer as its argument, like this:
- (void)narrationTimerDidFire:(NSTimer *)timer {
[self playNarrationForPage:timer.userInfo];
}
Then you need to use that selector when you create your timer:
NSTimer *narrationTimer = [NSTimer scheduledTimerWithTimeInterval:7.5
target:self
selector:@selector(narrationTimerDidFire:)
userInfo:[NSNumber numberWithInt:1]
repeats:NO];
If you really want to make narrationTimerDidFire:
call [super playNarrationForPage:]
, the compiler will let you. But doing that is very fishy . If you haven't overridden playNarrationForPage:
in your subclass, then there's no reason to refer to super
directly; your subclass inherits its superclass's playNarrationForPage:
method. If you have overridden playNarrationForPage:
in your subclass, then bypassing it from your timer's callback indicates that something is wrong with your design.
The only time you should use super
is when you are in a method and want to call the superclass's implementation of the same method (including indirectly -- see below).
self.superclass
doesn't make sense as the target of the timer unless your goal is to call a class method on the superclass.
Just use self
as the target. If that won't work because you are overriding playNarrationForPage:
and want to delay the invocation to super, then create a separate method that does something like:
- (void) _delayedDoIt
{
[super playNarrationForPage:1];
}
And call that from self's implementation of playNarrationForPage:
via the timer.
You cannot directly tell it to call the super
method. target
is only a pointer to an object, super
does not have a separate pointer address from your self
instance.
Also by assigning the target
to self.superclass
you are telling the target
to be the class. Therefore your trying call a class method rather than an instance method which is not what you want to do.
The only way to do this would be to assign target to self
and have a separate method such as:
- (void)callSuperMethod
{
[super playNarrationForPage:[NSNumber numberWithInt:1]];
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.