Objective-C消息机制
在Objective-C中我们可以向一个实例发送消息(方法调用),实例收到消息后会进行一些处理。
1、实例收到消息后,如果能respondsToSelector,那么就会调用相应的方法。
2、如果不能respond一般情况下会crash。
向一个实例发送一个消息后,系统处理的流程:
1. 发送消息如:[self startwork]
2. 系统会check是否能response这个消息
3. 如果能response则调用相应方法,不能则抛出异常
系统是如何check实例是否能response消息:
1、如果实例本身就有相应的response,那么就会响应之,
2、如果没有系统就会发出methodSignatureForSelector消息,寻问它这个消息是否有效?有效就返回对应的方法地址之类的,无效则返回nil。
重写methodSignatureForSelector时,需人工让其返回有效实例并分发给多个响应者。
3、如果是nil,Runtime则会发出-doesNotRecognizeSelector:消息,程序这时也就挂掉了。如果不是nil接着发送forwardInvocation消息。
@property (nonatomic, assign) BOOL silentWhenEmpty; // 找不到方法实现时是否抛错, 默认抛错。 @property (readonly, nonatomic) NSArray *plugins; // 判断super、plugin是否response - (BOOL)respondsToSelector:(SEL)selector { if ([super respondsToSelector:selector]) return YES; for (id plugin in _plugins){ if (plugin && [plugin respondsToSelector:selector]) return YES; } return NO; } // respondsToSelector返回No,进入该方法 - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector { NSMethodSignature *signature = [super methodSignatureForSelector:selector]; if (signature) return signature; if (self.silentWhenEmpty && _plugins.count == 0){ // 任意指定一个method signature return [self methodSignatureForSelector:@selector(description)]; } for (id plugin in _plugins){ if (!plugin) continue; signature = [plugin methodSignatureForSelector:selector]; if (signature) break; } return signature; } // 假如methodSignatureForSelector返回不是nil,进入该方法 - (void)forwardInvocation:(NSInvocation *)invocation { SEL selector = [invocation selector]; BOOL responded = NO; BOOL swallowed = NO; for (id plugin in _plugins){ if (plugin && [plugin respondsToSelector:selector]){ [invocation invokeWithTarget:plugin]; [invocation getReturnValue:(void *)&swallowed]; responded = YES; if (swallowed){ break; } } } if (!responded && !self.silentWhenEmpty) // 没响应,允许报错 [self doesNotRecognizeSelector:selector]; }
看更多内容,打开轻松学习之 Objective-C消息转发