iOS消息转发机制

2019-04-26  本文已影响0人  羞涩的老湿鸡

在iOS日常开发过程中,当我们所调用的方法不存在时,便会报这样一个异常错误。unrecognized selector sent to instance 0x000f0203ce

这种异常是由于我们没有去实现调用的方法造成的。解决方式也很简单,只要在对应的类或者其父类中添加相应的方法即可。而我们今天要讲的是另外一种解决方式。

iOS的消息转发


我们都知道iOS由于runtime机制的原因是一门动态运行时语言。因此我们可以在运行期间增加方法。

消息的动态转发机制分为三大步:

第一步:当我们所调用的方法不存在时,首先检测是否可以通过runtime动态添加方法,因此会先去调用以下方法。
+ (BOOL)resolveInstanceMethod:(SEL)sel;//通过对象调用则触发该方法
+ (BOOL)resolveClassMethod:(SEL)sel;//通过类方法调用则触发该方法

通过重写resolveInstanceMethod方法,使用class_addMethod动态添加方法
+(BOOL)resolveInstanceMethod:(SEL)sel {
     NSString *methodStr = NSStringFromSelector(sel);
     if ([methodStr isEqualToString:@"test:"]) {
        IMP timer = [[self class] instanceMethodForSelector:@selector(timerStart)];
        class_addMethod(self, sel, timer, "v@i");
        return YES;
     }
     return NO;

第二步:如果未能通过runtime动态添加方法,则会去询问是否可以通过其它类来解决该问题。询问时会自动调用以下方法。
- (id)forwardingTargetForSelector:(SEL)aSelector;

通过重写forwardingTargetForSelector方法,当test:方法在本类无法处理时,可交给BaseViewController类来进行处理。
- (id)forwardingTargetForSelector:(SEL)aSelector{
     NSString *seletorString = NSStringFromSelector(aSelector);
     if ([@"test:" isEqualToString:seletorString]) {
     BaseViewController *s = [[BaseViewController alloc] init];
     return s;
 }
     return [super forwardingTargetForSelector:aSelector];
 }

上一篇下一篇

猜你喜欢

热点阅读