轉註出:http://www.javashuo.com/article/p-xfketuno-hn.htmlhtml
使用NSProxy作替身,代理,多繼承,本質上都是用它來轉發消息給真身。spa
觀察頭文件,NSProxy自身實現了的方法以下:debug
+ (Class)class;//類方法不該該重寫
//普通消息轉發1 - (void)forwardInvocation:(NSInvocation *)invocation;//其實自身並無實現,調用報錯。須要子類實現。而且官方建議重寫。
//普通消息轉發2 - (nullable NSMethodSignature *)methodSignatureForSelector:(SEL)sel;//能夠重寫,而且官方建議重寫。 - (void)dealloc;//能夠重寫 - (void)finalize;//應該忽略的方法(垃圾回收) @property (readonly, copy) NSString *description;//能夠重寫 @property (readonly, copy) NSString *debugDescription;//能夠重寫 + (BOOL)respondsToSelector:(SEL)aSelector;//類方法不該該重寫
另外值得注意的是被註釋的快速轉發消息方法:代理
// - (id)forwardingTargetForSelector:(SEL)aSelector;
官方明確的暗示咱們要使用上上方代碼塊裏的普通消息轉發。其實NSproxy子類對象是響應這個方法的,探究這行註釋的緣由主要是由於協議<NSObject>code
- (BOOL)isEqual:(id)object;//能夠重寫,內部只比較地址沒比較哈希 @property (readonly) NSUInteger hash;//能夠重寫 @property (readonly) Class superclass;//能夠重寫 - (Class)class;//能夠重寫 - (instancetype)self;//能夠重寫,通常忽略 - (id)performSelector:(SEL)aSelector;//能夠重寫 - (id)performSelector:(SEL)aSelector withObject:(id)object;//能夠重寫 - (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;//能夠重寫 - (BOOL)isProxy;//返回YES,通常忽略 - (BOOL)isKindOfClass:(Class)aClass;//被主動轉發到自身的forwardInvocation:中處理 - (BOOL)isMemberOfClass:(Class)aClass;//被主動轉發到自身的forwardInvocation:中處理 - (BOOL)conformsToProtocol:(Protocol *)aProtocol;//被主動轉發到自身的forwardInvocation:中處理 - (BOOL)respondsToSelector:(SEL)aSelector;//若是不能響應也會被主動轉發到自身的forwardInvocation:中處理 - (instancetype)retain OBJC_ARC_UNAVAILABLE; - (oneway void)release OBJC_ARC_UNAVAILABLE; - (instancetype)autorelease OBJC_ARC_UNAVAILABLE; - (NSUInteger)retainCount OBJC_ARC_UNAVAILABLE; - (struct _NSZone *)zone OBJC_ARC_UNAVAILABLE; @property (readonly, copy) NSString *description;//能夠重寫 @optional @property (readonly, copy) NSString *debugDescription;//能夠重寫
這裏注意到了4個很特殊的方法:orm
- (BOOL)isKindOfClass:(Class)aClass; - (BOOL)isMemberOfClass:(Class)aClass; - (BOOL)conformsToProtocol:(Protocol *)aProtocol; - (BOOL)respondsToSelector:(SEL)aSelector;
前3個方法直接要求使用普通消息轉發來實現,因此一調用就跳進普通消息轉發從而繞開了快速轉發(- (id)forwardingTargetForSelector:(SEL)aSelector;)htm
NSProxy並無實現forwardInvocation:若是用戶也沒有實現的話它必定會產生崩潰。同理,末尾方法若是自身不能響應依然會要求使用普通消息轉發來實現。對象
第一個總結:blog
若是在NSProxy中只想使用快速轉發來完成功能的話就:1.必須單獨實現以上4個方法,或者2.既實現快速轉發又實現普通轉發;顯然1比較划算。繼承
第二個結論:
若是要極盡徹底地實現把全部消息都轉發給內部的真身,那麼應該要把上方標記'能夠重寫'的方法都重寫了。