title: “iOS消息转发”
date: 2016-03-22 13:48:38
tags:
消息转发这块,我学习了三次。2次看书,1次看博客。每次看的都很明白。但是由于开发中使用很少,好忘。所以这里记录下。方便日后查看。
消息转发我分2个阶段。
一 这个消息由自己(本类)来响应阶段。
- 当向一个A类发送未实现的消息时。A类会调用 + (BOOL)resolveInstanceMethod:(SEL)sel 这个方法,动态的添加一个Method来响应。(添加Method看下边代码)
二 由其他类来响应阶段。
- 当 + (BOOL)resolveInstanceMethod:(SEL)sel 方法返回NO,就会调用 - (id)forwardingTargetForSelector:(SEL)aSelector 方法,询问是否交给其他类响应此消息。(添加看下边代码)
- 如果 - (id)forwardingTargetForSelector:(SEL)aSelector 返回nil,调用 - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector 先进行方法签名,再调用 - (void)forwardInvocation:(NSInvocation *)anInvocation 方法进行转发。
图片来自 http://www.cocoachina.com/ios/20151208/14595.html
void run (id self, SEL _cmd)
{
NSLog(@"%@ %s", self, sel_getName(_cmd));
}
+ (BOOL)resolveInstanceMethod:(SEL)sel
{
// if (sel == @selector(run)) {
// class_addMethod(self, sel, (IMP)run, "v@:");
// return YES;
// }
return [super resolveInstanceMethod:sel];
}
- (id)forwardingTargetForSelector:(SEL)aSelector
{
// if (aSelector == @selector(run)) {
// return FWCar.new;
// }
return [super forwardingTargetForSelector:aSelector];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
NSString *sel = NSStringFromSelector(aSelector);
if ([sel isEqualToString:@"run"]) {
// 为转发方法手动生成签名
return [NSMethodSignature signatureWithObjCTypes:"v@:"];
}
return [super methodSignatureForSelector:aSelector];
}
- (void)forwardInvocation:(NSInvocation *)anInvocation
{
SEL sel = anInvocation.selector;
FWCar *car = FWCar.new;
if ([car respondsToSelector:sel]) {
// 唤醒这个方法
[anInvocation invokeWithTarget:car];
}
}