iOS Runtime详解(新手也看得懂)

2020-01-21 07:51:57刘景俊

动态方法解析

首先,Objective-C运行时会调用 +resolveInstanceMethod:或者 +resolveClassMethod:,让你有机会提供一个函数实现。如果你添加了函数并返回YES, 那运行时系统就会重新启动一次消息发送的过程。

实现一个动态方法解析的例子如下:


- (void)viewDidLoad {
 [super viewDidLoad];
 // Do any additional setup after loading the view, typically from a nib.
 //执行foo函数
 [self performSelector:@selector(foo:)];
}

+ (BOOL)resolveInstanceMethod:(SEL)sel {
 if (sel == @selector(foo:)) {//如果是执行foo函数,就动态解析,指定新的IMP
  class_addMethod([self class], sel, (IMP)fooMethod, "v@:");
  return YES;
 }
 return [super resolveInstanceMethod:sel];
}

void fooMethod(id obj, SEL _cmd) {
 NSLog(@"Doing foo");//新的foo函数
}

打印结果:

2018-04-01 12:23:35.952670+0800 ocram[87546:23235469] Doing foo

可以看到虽然没有实现foo:这个函数,但是我们通过class_addMethod动态添加fooMethod函数,并执行fooMethod这个函数的IMP。从打印结果看,成功实现了。

如果resolve方法返回 NO ,运行时就会移到下一步:forwardingTargetForSelector。

备用接收者

如果目标对象实现了-forwardingTargetForSelector:,Runtime 这时就会调用这个方法,给你把这个消息转发给其他对象的机会。

实现一个备用接收者的例子如下: