Objective-C
使用类别调配
@interface cA : NSObject {
}
@end
@implementation cA
+(NSString*) cClassFooA {
return @"class fooA";
}
-(NSString*) cFooA {
return @"fooA";
}
@end
@interface cB : NSObject {
}
@end
@implementation cB
+(NSString*) cClassFooB {
return @"class fooB";
}
-(NSString*) cFooB {
return @"fooB";
}
@end
NSObject+Swizzling.h
#import <Foundation/Foundation.h>
@interface NSObject (Swizzling)
+ (void)cExchangeClassWithCls1:(Class)cls1 Sel1:(SEL)sel1 Cls2:(Class)cls2 Sel2:(SEL)sel2;
+ (void)cExchangeInstanceWithCls1:(Class)cls1 Sel1:(SEL)sel1 Cls2:(Class)cls2 Sel2:(SEL)sel2;
@end
NSObject+Swizzling.m
#import "NSObject+Swizzling.h"
#import <objc/runtime.h>
@implementation NSObject (Swizzling)
+ (void)cExchangeClassWithCls1:(Class)cls1 Sel1:(SEL)sel1 Cls2:(Class)cls2 Sel2:(SEL)sel2 {
Method originalMethod = class_getClassMethod(cls1, sel1);
Method swizzledMethod = class_getClassMethod(cls2, sel2);
method_exchangeImplementations(originalMethod, swizzledMethod);
}
+ (void)cExchangeInstanceWithCls1:(Class)cls1 Sel1:(SEL)sel1 Cls2:(Class)cls2 Sel2:(SEL)sel2 {
Method originalMethod = class_getInstanceMethod(cls1, sel1);
Method swizzledMethod = class_getInstanceMethod(cls2, sel2);
method_exchangeImplementations(originalMethod, swizzledMethod);
}
@end
通过 Objective-C 使用
- (void)testCExchangeClass {
[NSObject cExchangeClassWithCls1:[cA class] Sel1:@selector(cClassFooA) Cls2:[cB class] Sel2:@selector(cClassFooB)];
XCTAssertEqual(@"class fooB", [cA cClassFooA]);
}
- (void)testCExchangeInstance {
[NSObject cExchangeInstanceWithCls1:[cA class] Sel1:@selector(cFooA) Cls2:[cB class] Sel2:@selector(cFooB)];
XCTAssertEqual(@"fooB", [[[cA alloc] init] cFooA]);
}
[将 Swift 添加为消费者]
通过 Swift 使用
func testCExchangeClass() {
NSObject.cExchangeClass(withCls1: sA.self, sel1: #selector(sA.sClassFooA), cls2: sB.self, sel2: #selector(sB.sClassFooB))
XCTAssertEqual("class fooB", sA.sClassFooA())
}
func testCExchangeInstance() {
NSObject.cExchangeInstance(withCls1: sA.self, sel1: #selector(sA.sFooA), cls2: sB.self, sel2: #selector(sB.sFooB))
XCTAssertEqual("fooB", sA().sFooA())
}
[快速混搭]