1.
#import "UIView+Test.h" @implementation UIView (Test) + (BOOL)resolveInstanceMethod:(SEL)sel { return NO; } - (id)forwardingTargetForSelector:(SEL)aSelector { NSString *sel = NSStringFromSelector(aSelector); if ([sel isEqualToString:@"setImage:"]) { return [UIImageView new]; } return [super forwardingTargetForSelector:aSelector]; } @end
在Objective-C中,在调用对象的某个方法时,其实是在向这个对象发送消息。系统会查看这个对象能否接收该消息,如果不能,则会进行消息转发,消息转发最多三个步骤(注:如果前一步成功处理了消息,那么就不会走到下一步):
-
调用
resolveInstanceMethod:
或resolveClassMethod:
来决定是否动态添加方法。如果动态添加,则消息得到处理,消息转发结束;否则,进入下一步。 -
调用
forwardingTargetForSelector:
来确定能不能把这条消息转给其他接收者处理,如果返回一个非self
的对象,则会把消息发送给该对象,消息转发结束;否则,进入下一步。 -
通过
methodSignatureForSelector:
方法获取签名,如果签名为nil,则消息无法处理,抛出异常;否则,调用forwardInvocation:
方法,调用成功则消息转发结束,调用失败则消息无法处理,抛出异常。