NSProxy和class NSObject平级,彼此没有继承关系;唯一的相同点是它们都遵循protocol NSObject,NSProxy没有init方法,不能直接使用,需要子类继承,之后使用
用途
1:解决循环依赖,最典型用途解除对NSTimer对self的应用
2:解觉向Array中添加weak指针的问题
将一个weak指针通过[array ddObject:obj]添加到数组,会对指针进行值拷贝,并且是强引用,所以,将weak类型的指针加入数组,会对原对象强引用。解决方案就是使用NSProxy,NSProxy若持有weak对象,然后将NSProxy对象加入数组,数组对NSProxy对象强引用
NSProxy和NSObject转发机制的不同
对于class NSObject而言,接收到消息后先去自身的方法列表里找匹配的 selector,如果找不到,会沿着继承体系去 superclass 的方法列表找;如果还找不到,先后会经过+resolveInstanceMethod:和-forwardingTargetForSelector:处理,处理失败后,才会到-methodSignatureForSelector:/-forwardInvocation:进行最后的挣扎
但对于NSProxy,接收 unknown selector 后,直接回调-methodSignatureForSelector:/-forwardInvocation:,消息转发过程比class NSObject要简单得多
NSProxy的方法调用
1 NSObject协议中的判断方法
这些方法包括
- (BOOL)isKindOfClass:(Class)aClass;
- (BOOL)isMemberOfClass:(Class)aClass;
- (BOOL)conformsToProtocol:(Protocol *)aProtocol;
- (BOOL)respondsToSelector:(SEL)aSelector;
会在内部调用methodSignatureForSelector:/-forwardInvocation:进行转发,转发到其他对象执行,实际响应对象是其他对象
methodSignatureForSelector走转发流程,但是forwardInvocation没走转发流程,直接调用forwardInvocation转发,这些方法是
我们可以看一下调用的这些方法堆栈
可以看到在方法内部,methodSignatureForSelector,走转发流程
forwardInvocation不走转发流程
2 其他NSProxy实现的方法
对于已经实现的方法可以直接调用该方法,响应对象是NSProxy对象
例如:NSObject协议里的方法,NSProxy如果有实现,那么响应对象是NSProxy本身。例如isProxy等,NSProxy基类有实现,实际响应对象是NSProxy对象
3 NSProxy没实现的方法
NSProxy没有实现的方法,经过转发流程methodSignatureForSelector:/-forwardInvocation:进行转发,响应对象是其他对象
总结一下
1NSObject协议中的上述判断方法,NSProxy在方法内部实现的时候,将消息转发到其他对象
2 NSObject协议的其他方法,响应对象是NSProxy自身
3 其他没实现的方法,走方法转发流程,转发到其他对象