iOS - Cannot use 'super' as a reference?
Asked Answered
S

2

6

I'm trying to use an NSInvocation to invoke a superclass method from the subclass. The code involved is relatively straightforward, it goes like:

- (NSInvocation*) invocationWithSelector:(SEL)selector {
    NSInvocation* call = [[NSInvocation alloc] init];
    [call retainArguments];
    call.target = super;  //ERROR:  use of undeclared identifier 'super'

    call.selector = @selector(selector);

    return call;
}

This seems a bit odd to me, as I had always assumed that super followed pretty much the same rules as self (i.e. it could be treated as a direct reference to the object in question and assigned to variables, used as a return value, etc.). It appears that this is not the case in practice.

Anyhow, is there any simple way to get my NSInvocation to target the superclass implementation (I cannot use self as the target, because the subclass overrides the superclass methods), or do I need to look for some other approach?

Song answered 14/5, 2012 at 6:47 Comment(1)
does self.superclass work? (just guessing here...)Aldric
C
9

See What exactly is super in Objective-C? for more info, but super is not actually an object. Super is a keyword for the compiler to generate obj-c runtime calls (specifically objc_msgSendSuper). Basically, it is like casting your class to its superclass before sending it the message.

EDIT So if you've overriden the method you want to call, you are going to have to write another method to call [super method] directly and set your invocation to call that method instead. The runtime will only send messages to objects, and they will be dealt with at the lowest member of the inheritance chain that implements them.

Counterpoison answered 14/5, 2012 at 7:0 Comment(5)
Interesting, so essentially you cannot indirectly invoke a superclass method using NSInvocation or performSelector... if your subclass provides its own implementation of the target method? That seems like a bit of a limitation.Song
Does it? Does C++ or another C based language allow you to do this? I mean, if you override functionality it means you want behavior on your class that is different from that of its parent class (or in addition to that of its parent class). If this is not the correct idea then I suppose I have a fundamental flaw in my understanding of OOP.Counterpoison
No, it does not appear that other languages allow this (just tried with Java, same issue). But you hit the key point with your "in addition to that of its parent class" comment. The subclass has the ability to explicitly invoke the superclass implementation of an overridden method, as it well should. And because of that I see no logical reason why it should not be able to implicitly do the same thing using an NSInvocation or a performSelector... call. In short, I don't think it makes sense for calls to the superclass implementation to require an explicit/immediate invocation.Song
what I meant by in addition was that it calls [super method] before going on to do other things ^^;. If you want to be hardcore, you can switch the implementations of your two functions at runtime (don't forget to switch them back) via method swizzling. See this page: cocoawithlove.com/2008/03/supersequent-implementation.html You can swap the implementations of your subclass and superclass and they will be called backwards to what you think (which is why this is hardcore and scary) and your invocation will actually execute the superclass IMP.Counterpoison
However, keeping track of when you switched them seems to be the same amount of bother as just keeping track of when to explicitly call [super].Counterpoison
H
1

super and self are the same object, so just use

call.target = self;

The difference between them is that you can use super as a receiver of a message to self as a way to ensure that it invokes the superclass' implementation.

Haemolysin answered 14/5, 2012 at 6:50 Comment(1)
Did you mean to type "self" ?Counterpoison

© 2022 - 2024 — McMap. All rights reserved.