您的位置:

详解iOS消息转发机制

一、iOS消息转发机制原理

iOS的消息转发是指在某个对象接收到一个消息(调用一个方法)时,如果该对象无法响应这个消息,那么就会进入消息转发机制,尝试将消息转发给其他对象进行响应。

具体的消息转发机制分为三个步骤:

1、动态方法解析:当接收到无法响应的消息时,首先会走动态方法解析,如果该对象的类有实现 +resolveInstanceMethod: 方法的话,那么就尝试通过这个方法为当前类动态添加能够响应该消息的方法。

示例代码:

``` + (BOOL)resolveInstanceMethod:(SEL)sel { if (sel == @selector(demoMethod)) { class_addMethod([self class], sel, (IMP) demoMethodIMP, "@:"); return YES; } return [super resolveInstanceMethod:sel]; } void demoMethodIMP(id self, SEL _cmd) { NSLog(@"动态添加方法demoMethod"); } ```

2、备用接收者:如果动态方法解析失败,那么就会尝试将消息转发给另外一个对象进行响应,这个对象就是备用接收者,通常是该对象的某个属性。

示例代码:

``` - (id)forwardingTargetForSelector:(SEL)aSelector { if ([NSStringFromSelector(aSelector) isEqualToString:@"demoMethod"]) { return [AnotherObject new]; } return [super forwardingTargetForSelector:aSelector]; } ```

3、完整的消息重定向:当备用接收者也无法响应该消息时,程序就会走完整的消息重定向机制,这个机制最终会将无法响应的消息发送给一个默认的接收对象进行处理,也就是 NSObject 类中的 `doesNotRecognizeSelector` 方法。

示例代码:

``` - (void)forwardInvocation:(NSInvocation *)anInvocation { NSLog(@"消息转发"); [super forwardInvocation:anInvocation]; } - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { if(selector == @selector(demoMethod)) { return [NSMethodSignature signatureWithObjCTypes:"v@:"]; } return [super methodSignatureForSelector:selector]; } ```

二、iOS消息转发解决崩溃

在使用 iOS 的消息转发机制时,可能会出现一些难以调试和捕捉的崩溃,这是由于在 Objc 的 runtime 时间动态加载方法,进行调用方法指针时,如果指针为 NULL 时,系统就会抛出一个错误信号 SIGSEGV。

对于这种崩溃,我们需要在消息转发机制中进行容错处理,避免因为一个方法不存在而导致整个程序崩溃。

示例代码:

``` - (void)forwardInvocation:(NSInvocation *)anInvocation { if([self respondsToSelector:anInvocation.selector]) { [anInvocation invokeWithTarget:self]; }else { [super forwardInvocation:anInvocation]; } } - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { NSMethodSignature * methodSignature = [super methodSignatureForSelector:aSelector]; if (!methodSignature) { methodSignature = [self.myFallbackObject methodSignatureForSelector:aSelector]; } return methodSignature; } ```

三、iOS消息转发机制面试

在 iOS 面试过程中,消息转发机制是一个常见的面试题目。由于消息转发机制的复杂性,面试官通常会从以下几个方面来评测候选人的能力:

1、对 iOS 消息转发机制原理的理解程度,以及能否准确地进行操作;

2、候选人在解决某个 bug 时是否能够合理地运用消息转发机制;

3、题目细节问题的解决能力,比如在什么情况下,备用接收对象和完整消息重定向的顺序会发生变化等。

四、iOS 开发 runtime 消息转发机制

iOS 开发中,能够灵活地处理消息转发机制是非常重要的。而基于 Objc 的 runtime,我们可以在运行时动态地接收和处理一些原本无法处理的消息。

示例代码:

``` - (void)forwardInvocation:(NSInvocation *)anInvocation { SEL selector = [anInvocation selector]; if ([self.delegate respondsToSelector:selector]) { [anInvocation invokeWithTarget:self.delegate]; } } - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { NSMethodSignature * signature = [super methodSignatureForSelector:selector]; if (!signature) { if ([self.delegate respondsToSelector:selector]) { return [(id)self.delegate methodSignatureForSelector:selector]; } } return signature; } ```

五、iOS消息发送机制

iOS的消息发送机制是指在程序中调用一个方法时,编译器将这个方法名编码为一个唯一的 SEL 对象,同时为其生成一段汇编代码。在执行这段代码时,会将这个 SEL 发送给接收者对象进行响应。

示例代码:

``` [self performSelector:@selector(demoMethod)]; ```

六、iOS的消息推送机制

iOS的消息推送是指当应用程序在后台运行时,即使应用程序已经关闭,仍然能够接收到新的消息推送通知。这个功能需要借助后台通知技术来实现。当服务器有新的消息推送时,可以通过 APNs(苹果消息推送服务)来推送给用户设备。

示例代码:

``` - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { NSString *token = [[[[deviceToken description] stringByReplacingOccurrencesOfString:@"<"withString:@""] stringByReplacingOccurrencesOfString:@">" withString:@""] stringByReplacingOccurrencesOfString:@" " withString:@""]; } ```