这两种混合方式之间存在细微差别。我只想澄清它们之间是否有根本不同或错误
假设我们在viewDidLoad
UIView
第一种方式(使用class_addMethod
):
@implementation UIView (SwizzleFirstWay)
+ (void)load {
SEL originalSelector = @selector(viewDidLoad);
SEL swizzledSelector = @selector(swizzled_viewDidLoad);
Method originalMethod = class_getInstanceMethod(self, originalSelector);
Method swizzledMethod = class_getInstanceMethod(self, swizzledSelector);
class_addMethod(self,
originalSelector,
class_getMethodImplementation(self, originalSelector),
method_getTypeEncoding(originalMethod));
// Adding the method
class_addMethod(self,
swizzledSelector,
class_getMethodImplementation(self, swizzledSelector),
method_getTypeEncoding(swizzledMethod));
method_exchangeImplementations(originalMethod, swizzledMethod);
}
+ (void)swizzled_viewDidLoad {
// ... the swizzled implementation
// ...
// ...
[self swizzled_viewDidLoad]; // calling back to the original implementation
}
@end
第二种方式(不使用class_addMethod
):
+ (void)load {
SEL originalSelector = @selector(viewDidLoad);
SEL swizzledSelector = @selector(swizzled_viewDidLoad);
Method originalMethod = class_getInstanceMethod(self, originalSelector);
Method swizzledMethod = class_getInstanceMethod(self, swizzledSelector);
// NOT USING class_addMethod
method_exchangeImplementations(originalMethod, swizzledMethod);
}
+ (void)swizzled_viewDidLoad {
// ... the swizzled implementation
// ...
// ...
[self swizzled_viewDidLoad]; // calling back to the original implementation
}
@end
答案 0 :(得分:0)
非常好的问题,实际上。如果您先使用t = [(3,300),(1,100),(2,200),(4,400),(5,500)]
t.sort()
print(t)
t = t[0:3]
print(t)
而不先调用method_exchangeImplementations
,则可能会意外地调动您的超类实现。原因是class_addMethod
在类本身没有实现方法的情况下搜索超类的继承实现。显然,这不是你想要实现的目标。
一个简单的例子。使用以下代码
class_getInstanceMethod
结果
- [UICheckeredPatternView swizzled_removeFromSuperview]:无法识别的选择器发送到实例0x101b24250
因为@interface UIWebView (SwizzlingTest)
- (void)swizzled_removeFromSuperview {
[self swizzled_removeFromSuperview];
}
+ (void)load {
SEL originalSelector = @selector(removeFromSuperview);
SEL swizzledSelector = @selector(swizzled_removeFromSuperview);
Method originalMethod = class_getInstanceMethod(self, originalSelector);
Method swizzledMethod = class_getInstanceMethod(self, swizzledSelector);
method_exchangeImplementations(originalMethod, swizzledMethod);
}
@end
继承自removeFromSuperview
,但未在UIView
中实施。