您的位置:首页 > 移动开发 > Objective-C

Objective-C Runtime (一)

2015-08-11 22:15 459 查看

感受

淡到runtime ,让我们先感受一下它的黑魔法,欺诈(swizz),先写一点代码,感受一下

1.新建一个项目, SingleViewApplication 然后选择默认的ViewController.m

2.一个APP 运行的时候会先将类 load 到内存中,相当于电脑程序启动的时候,将程序资源从硬盘放到内存中一样

3.包含头文件 既然要使用runtime ,那就要包含头文件 obj/runtime.h

4.在 ViewController.m 文件,重写父类方法 + (void)load

5.写下如下代码

+ (void)load{

static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{

Class class = [self class];

SEL originalSelector = @selector(viewWillAppear:);
SEL swizzledSelector = @selector(my_viewWillAppear:);

Method originalMethod = class_getInstanceMethod(class , originalSelector);
Method swizzledMethod = class_getInstanceMethod(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);
}

});
}


6.然后重写继承的一个方法

//view 即将显示的时候调用,一般不要在这个方法中写太多代码,这里用于测试
- (void)viewWillAppear:(BOOL)animated{

NSLog(@"viewWillAppear 哈哈");

[super viewWillAppear:animated];
}


7.增加一个自己的方法 hehe:

- (void)hehe:(BOOL)animated{
NSLog(@"hehe 呵呵");
}


好了,让我们command + R 吧,编译运行,输出结果为



没看错,并没有运行 * viewWillAppear:(BOOL)animated * 这里面的代码

让我们在见证一下在 viewDidLoad 手动调用viewWillAppear: 这个方法

- (void)viewDidLoad {
[super viewDidLoad];
//手动调用
[self viewWillAppear:YES];
}


看看运行结果



结论

好像 viewWillAppear: 这个方法的代码永远不会被执行一样,但是却响应了这个消息viewWillAppear,只是执行的代码是hehe:方法中的代码,那么原因是什么?

在该类被加载到内存的时候也就是第一次 [b]+load 的时候,使用了几个C语言的函数,将viewWillAppear消息(消息的名字不是这个)在运行时态对应的方法,给替换了,那么当消息循环收到这个消息的时候,就自己寻找到了对应的方法执行[/b]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: