Call super without "super" keyword

ios, iphone, objective-c, objective-c-runtime

Solution

You will have to

- get the receivers class (e.g. with `object_getClass(rcv)`)

- then get the super class of it (with `class_getSuperclass(class)`)

- then get the implementation of it (with `class_getMethodImplementation(superclass, sel)`)

- then call the imp.

done

Stop at any step if you got nil or NULL.

Oh, and all this seems silly. But I assume that the question just lacks of context to see the motivation for such a hack.

[Update]

An explanation for future readers:

The `super` keyword is resolved at compile time. Therefore it does not the intended thing when changing methods at runtime. A method which is intended to be injected in some object (and its class hierarchy) at runtime has to do super calls via runtime as outlined above.

Problem

I want' to implement "Fix and continue functionality" that was in Xcode 3. CONTEXT: The main idea is: When I need to "Fix something fast", I'm not re-compiling, project. I'm compiling small `Attacker class` with 'updated' method implementation, loading it into memory and replacing VictimClass's method which have `incorrect` implementation in runtime. I think that this method will work faster that full project recompilation. When i'm done with fixes i'm just copying source of `Attacker class` method to `Victim class`. PROBLEM At the moment, I don't know how correctly call `[super ...]` in Attacker class. For example, i have VictimClass ``` @interface VictimClass : UIView @end @implementation VictimClass - (void)drawRect:(CGRect)rect { [super drawRect:rect]; } @end @interface AttackerClass : NSObject @end @implementation AttackerClass - (void)drawRect:(CGRect)rect { [super drawRect:rect]; [self setupPrettyBackground]; } @end .... // EXCHANGE IMPLEMENTATIONS Method m = class_getInstanceMethod([AttackerClass class], @selector(drawRect:)); const char * types = method_getTypeEncoding(m); IMP attackerImp = method_getImplementation(m); class_replaceMethod([VictimClass class], @selector(drawRect:), attackerImp, types); // Invoking drawRect on Victim VictimClass * view = /* */; [view setNeedsDisplay]; ``` At this point , when `drawRect:` method will be called, this will lead to exception, since `drawRect:` will be called on NSObject class, but not on UIView class So, my question is, how correctly call `[super drawRect:]` in AttackerClass, to have possibility to correctly exchange implementation in runtime? Main idea is to provide a way to correctly replace any method in Victim class by Attacker's class method. Generally, you don't know, superclass of `Victim class`. UPDATE: Replacing implementation code added.

Original source