第13条:用“方法调配技术”调试“黑盒方法”
1.方法调配的概念
(1)在运行期,可以向类中新增或替换选择子所对应的方法实现
(2)使用另一份实现替换原来方法的实现,这叫“方法调配”,此技术可向原有实现中添加新功能
(3)不宜滥用
2.具体使用
在+load中执行
在dispatch_once中执行
method_exchangeImplementations(A,B) :交换方法AB
class_replaceMethod :修改类
class_getInstanceMethod(Class aClass, SEL aSelector) :从类中取出与之相关的方法
3.应用1-交换方法
// 交换方法
Method originalMethod = class_getInstanceMethod([NSStringclass], @selector(lowercaseString));
Method swappedMethod =
class_getInstanceMethod([NSStringclass],
@selector(uppercaseString));
method_exchangeImplementations(originalMethod, swappedMethod);
// 使用
NSString *string = @"ThIs iS tHe StRiNg";
NSString *lowercaseString = [string lowercaseString];
NSLog(@"lowercaseString = %@", lowercaseString);
// Output: lowercaseString = THIS IS THE STRING
NSString *uppercaseString = [string uppercaseString];
NSLog(@"uppercaseString = %@", uppercaseString);
// Output: uppercaseString = this is the string
4.应用2-添加新功能
- 新方法可以添加至NSString的一个“分类”(category)中:
@interface NSString (EOCMyAdditions)
- (NSString*)eoc_myLowercaseString;
@end
- 新方法的实现代码可以这样写:
@implementation NSString (EOCMyAdditions)
- (NSString*)eoc_myLowercaseString {
NSString *lowercase = [self eoc_myLowercaseString];
NSLog(@"%@ => %@", self, lowercase);
return lowercase;
}
@end
- 通过下列代码来交换这两个方法实现:
Method originalMethod =
class_getInstanceMethod([NSString class],
@selector(lowercaseString));
Method swappedMethod =
class_getInstanceMethod([NSString class],
@selector(eoc_myLowercaseString));
method_exchangeImplementations(originalMethod, swappedMethod);
- 调用lowercaseString方法,并输出
NSString *string = @"ThIs iS tHe StRiNg";
NSString *lowercaseString = [string lowercaseString];
// Output: ThIs iS tHe StRiNg => this is the string