method swizzling使用一例

来源:互联网 发布:qq国际版for ubuntu 编辑:程序博客网 时间:2024/06/08 20:00

**Method swizzling** 是改变selector(选择器)实现的一个的过程,这个技术依赖于Object-C的方法调用可以通过运行时进行拦截(改变),具体做法就是改变类的调度表(dispatch table)中selector(选择器)到最终函数间的映射关系。

举个例子,假如我们想跟踪每个控制器在某个程序中展示给用户的次数:那么可以在每个控制器的viewDidAppear 的实现里面添加跟踪的代码,但是这样会导致大量的重复代码。通过继承可以解决重复代码的问题,可即使使用继承,在 UIViewController, UITableViewController, UINavigationController和其他类型的 view controller 里面的viewDidAppear方法依然会存在大量重复代码。但幸运的是,我们有Method swizzling

\#import @implementation UIViewController (Tracking)+ (void)load { static dispatch\_once\_t onceToken; dispatch\_once(&onceToken, ^{ Class class = [self class]; SEL originalSelector = @selector(viewWillAppear:); SEL swizzledSelector = @selector(xxx\_viewWillAppear:); Method originalMethod = class\_getInstanceMethod(class, originalSelector); Method swizzledMethod = class\_getInstanceMethod(class, swizzledSelector); // When swizzling a class method, use the following: // Class class = object\_getClass((id)self); // ... // Method originalMethod = class\_getClassMethod(class, originalSelector); // Method swizzledMethod = class\_getClassMethod(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); } });}\#pragma mark - Method Swizzling- (void)xxx\_viewWillAppear:(BOOL)animated { [self xxx\_viewWillAppear:animated]; NSLog(@"viewWillAppear: %@", self);}@end````

在计算机科学中,pointer swizzling 就是一种引用的变换,基于位置和名称的指向引用的变换。在原生的Objective-C关于Method swizzling的说明并不是很公开,但Method Swizzling的存在依然很容易理解,因为它能够通过@selector来改变函数指针的引用。

现在,当UIViewController或它子类的任何实例触发viewWillAppear:方法都会打印一条log日志。

向视图控制器的生命周期中注入操作、事件的响应、视图的绘制,或Foundation中的网络堆栈都是能够利用method swizzling产生明显效果的场景。。

原创粉丝点击