iOS消息转发机制

在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];
 }

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容