I want to test method swizzling in Objective-C:
Add a method goodName
in AViewController
#import "AViewController.h"
#import "UIViewController+Tracking.h"
@interface AViewController ()
@end
@implementation AViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self goodName];
}
- (void) goodName {
NSLog(@"I am a good Name");
}
@end
Add a category for swizzling goodName
method.
#import "UIViewController+Tracking.h"
#import <objc/runtime.h>
#import "AViewController.h"
@implementation UIViewController (Tracking)
+ (void) load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
SEL originalSelector = @selector(goodName);
SEL swizzledSelector = @selector(xxx_xxx_goodName);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);
BOOL didAddMethod = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
});
}
- (void)xxx_xxx_goodName {
NSLog(@"i am xxx goodName");
[self xxx_xxx_goodName];
}
@end
If everything works well, the goodName
was called will output i am xxx goodName
, but it's output I am a good Name
.
Any part wrong?
You're trying to swizzle methods in AViewController but you put the code in +(void)load
for base UIViewController. Those are two separate class objects so you need to do it in +(void)load
for AViewController.