NSProxy

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,走转发流程


image.png

forwardInvocation不走转发流程


image.png

2 其他NSProxy实现的方法

对于已经实现的方法可以直接调用该方法,响应对象是NSProxy对象

例如:NSObject协议里的方法,NSProxy如果有实现,那么响应对象是NSProxy本身。例如isProxy等,NSProxy基类有实现,实际响应对象是NSProxy对象

3 NSProxy没实现的方法

NSProxy没有实现的方法,经过转发流程methodSignatureForSelector:/-forwardInvocation:进行转发,响应对象是其他对象


image.png

image.png

总结一下

1NSObject协议中的上述判断方法,NSProxy在方法内部实现的时候,将消息转发到其他对象
2 NSObject协议的其他方法,响应对象是NSProxy自身
3 其他没实现的方法,走方法转发流程,转发到其他对象

参考文档:https://zhangbuhuai.com/post/nsproxy.html

你可能感兴趣的:(NSProxy)