在Objective-C中咱们能够向一个实例发送消息(方法调用),实例收到消息后会进行一些处理。html
一、实例收到消息后,若是能respondsToSelector,那么就会调用相应的方法。ios
二、若是不能respond通常状况下会crash。学习
向一个实例发送一个消息后,系统处理的流程:atom
1. 发送消息如:[self startwork]spa
2. 系统会check是否能response这个消息code
3. 若是能response则调用相应方法,不能则抛出异常htm
系统是如何check实例是否能response消息:blog
一、若是实例自己就有相应的response,那么就会响应之,ip
二、若是没有系统就会发出methodSignatureForSelector消息,寻问它这个消息是否有效?有效就返回对应的方法地址之类的,无效则返回nil。get
重写methodSignatureForSelector时,需人工让其返回有效实例并分发给多个响应者。
三、若是是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消息转发