method swizzling使用一例

**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产生明显效果的场景。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值