Override the method via ObjC Category and call the default implementation?

When using categories, you can override implementation methods with your own, for example:

// Base Class @interface ClassA : NSObject - (NSString *) myMethod; @end @implementation ClassA - (NSString*) myMethod { return @"A"; } @end //Category @interface ClassA (CategoryB) - (NSString *) myMethod; @end @implementation ClassA (CategoryB) - (NSString*) myMethod { return @"B"; } @end 

Calling the "myMethod" method after including a category sets the result to "B".

What is the easiest way to implement the myMethod class to call the source myMethod class? As far as I can tell, you'll have to use low level calls to get the original hook method for class A and call it, but it seemed like it would be a syntactically simpler way to do this.

+47
objective-c
Jul 06 '09 at 4:53
source share
4 answers

If you need a hacky way to do this related to running the objective-c environment, you can always use the method

+37
Jul 6 '09 at 5:15
source share

From comp.lang.objective-C Frequently Asked Questions : " What if several categories implement the same method? Then the fabric of the Universe, as we know it, ceases to exist. In fact, this is not entirely true, but, of course, some problems will be caused.When a category implements a method that has already appeared in the class (either through another category or class' primary @implementation), this category definition overwrites the previously existing definition.The original definition can no longer be reached using Objective-C code Note that e whether two categories overwrite the same method, whichever was last loaded "wins" that may be impossible to predict before running code. "

From developer.apple.com : "When a category overrides an inherited method, a method in a category can, as usual, invoke an inherited implementation via a message for super. However, if a category overrides a method that already existed in the category class, there is no way to invoke the original implementation"

+19
Jul 06 '09 at 5:04
source share

Check out my article on the solution found in the Mac Developer Library: http://codeshaker.blogspot.com/2012/01/calling-original-overridden-method-from.html

Basically, this is the same as the Swizzling method described above with a brief example:

 #import <objc / runtime.h>

 @implementation Test (Logging)

 - (NSUInteger) logLength {
     NSUInteger length = [self logLength];
     NSLog (@ "Logging:% d", length);
     return length;
 }

 + (void) load {
     method_exchangeImplementations (class_getInstanceMethod (self, @selector (length)), class_getInstanceMethod (self, @selector (logLength)));
 }

 @end
+12
Jan 23 2018-12-12T00:
source share

With the swizzling "helper" methods included in ConciseKit , you actually invoke the default implementation ... strangely enough ... by invoking your SWIZZLED implementation ..

You set it to + (void) load by calling + (BOOL)swizzleMethod:(SEL)originalSelector with:(SEL)anotherSelector in:(Class)klass; , i.e.

 [$ swizzleMethod:@selector(oldTired:) with:@selector(swizzledHotness:) in:self.class]; 

and then in the swizzled method .. suppose it returns -(id) .. you can do your evil or whatever reason that you first launched ... and then instead of returning the object or self , or something else.

 return [self swizzledHotness:yourSwizzledMethodsArgument]; 

As explained here ...

In this method, it looks like we are calling the same method again, calling infinite recursion. But by the time this line is reached, both methods have been replaced. Therefore, when we call swizzled_synchronize, we actually call the original method.

It feels and looks weird, but .. it works. This allows you to add endless embellishments to existing methods and still β€œcall super” (actually β€œme”) and take advantage of the original handiwork method ... even without access to the original source.

+1
Apr 10 '13 at 16:12
source share



All Articles