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?

Monolo
  • 18,205
  • 17
  • 69
  • 103
aroth
  • 54,026
  • 20
  • 135
  • 176

2 Answers2

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.

Community
  • 1
  • 1
borrrden
  • 33,256
  • 8
  • 74
  • 109
  • 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. – aroth May 14 '12 at 10:33
  • 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. – borrrden May 14 '12 at 14:18
  • 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. – aroth May 14 '12 at 23:25
  • 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: http://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. – borrrden May 14 '12 at 23:43
  • 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]. – borrrden May 14 '12 at 23:43
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.

Monolo
  • 18,205
  • 17
  • 69
  • 103