我想尝试使用Method Swizzling清楚地了解它是如何工作的。 看看这段代码:http://nshipster.com/method-swizzling/。 我创建了一个类和一个类别,这里是代码
#import <Foundation/Foundation.h>
@interface CustomClass : NSObject
-(void) originalMethod;
@end
课程的实施
#import "CustomClass.h"
@implementation CustomClass
-(id) init {
self = [super init];
return self;
}
-(void) originalMethod {
NSLog(@"I'm the original method");
}
@end
类别标题:
#import "CustomClass.h"
@interface CustomClass (CustomCategory)
-(void) newMethod;
@end
类别实施
#import "CustomClass+CustomCategory.h"
#include <objc/runtime.h>
@implementation CustomClass (CustomCategory)
-(void) newMethod {
[self newMethod];
NSLog(@"I'm the new method");
}
+(void) load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Class class = [self class];
// When swizzling a class method, use the following:
// Class class = object_getClass((id)self);
SEL originalSelector = @selector(originalMethod:);
SEL swizzledSelector = @selector(newMethod:);
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);
}
});
}
@end
这是主要的:
#import <Foundation/Foundation.h>
#import "CustomClass.h"
#import "CustomClass+CustomCategory.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
CustomClass *cc = [[CustomClass alloc] init];
[cc newMethod];
}
return 0;
}
当我打电话给[cc newMethod]
时,我得到了无限循环,这根据我链接的文章不应该发生。
我无法在此代码中看到错误。
答案 0 :(得分:1)
问题在于语法,而不是
SEL originalSelector = @selector(originalMethod:);
SEL swizzledSelector = @selector(newMethod:);
我应该写:
SEL originalSelector = @selector(originalMethod);
SEL swizzledSelector = @selector(newMethod);
答案 1 :(得分:0)
class_replaceMethod(class,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
不应method_getImplementation(originalMethod)
为swizzledMethod
?
答案 2 :(得分:0)
好像你在调整类方法:
Class class = [self class];
指向+load
上下文中的元类,尝试明确指定它,即
Class class = [CustomClass class];
// or
Class class = self;
另外,@ bbum说什么
答案 3 :(得分:0)
语法错误,运行时会发送不同的消息。
BOOL didAddMethod =
class_addMethod(class, originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
如果第一种方式无效。试试吧:
File.separator
交换实施可能会有效。