首先展示一个NSProxy使用的例子。
NSProxy使用示例
@interface BDWeakProxy : NSProxy
@property (nonatomic, weak) id target;
@end
@implementation BDWeakProxy
- (instancetype)initWithTarget:(id)target {
self.target = target;
return self;
}
- (void)forwardInvocation:(NSInvocation *)invocation {
[invocation invokeWithTarget:self.target];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
return [self.target methodSignatureForSelector:sel];
}
@end
根据官方文档,通过重写这两个方法,就可以利用BDWeakProxy来进行消息转发到target。
但是如果用NSObject实现呢?
@interface BDWeakProxy : NSObject
@property (nonatomic, weak) id target;
@end
@implementation BDWeakProxy
- (instancetype)initWithTarget:(id)target {
self = [super init];
if (self) {
self.target = target;
}
return self;
}
- (void)forwardInvocation:(NSInvocation *)invocation {
[invocation invokeWithTarget:self.target];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
return [self.target methodSignatureForSelector:sel];
}
@end
同样可以做到消息转发,这两个又有什么区别呢?
NSProxy不同之处
NSProxy类是没有init方法的NSProxy是一个抽象类,且父类不是NSObject- 一些
NSObject有的方法NSProxy没有实现 NSProxy的消息转发机制
下面展示一下一般对象的消息转发机制。
消息转发机制这个就不用解释了,上面两个例子最终转发都是利用了消息转发机制,到最后一步实现消息转发到target。
这篇文章中提说,通过继承自NSObject的代理类是不会自动转发respondsToSelector:和isKindOfClass:这两个方法的, 而继承自NSProxy的代理类却是可以的. 测试中定义的其它接口二者表现都是一致的.
实际原因:
NSProxy没有实现respondsToSelector:和isKindOfClass:这两个方法,故而转发。NSObject有实现。
NSProxy的消息转发机制
其实重点在于NSProxy的方法。
NS_ROOT_CLASS
@interface NSProxy <NSObject> {
Class isa;
}
+ (id)alloc;
+ (id)allocWithZone:(nullable NSZone *)zone NS_AUTOMATED_REFCOUNT_UNAVAILABLE;
+ (Class)class;
- (void)forwardInvocation:(NSInvocation *)invocation;
- (nullable NSMethodSignature *)methodSignatureForSelector:(SEL)sel NS_SWIFT_UNAVAILABLE("NSInvocation and related APIs not available");
- (void)dealloc;
- (void)finalize;
@property (readonly, copy) NSString *description;
@property (readonly, copy) NSString *debugDescription;
+ (BOOL)respondsToSelector:(SEL)aSelector;
- (BOOL)allowsWeakReference NS_UNAVAILABLE;
- (BOOL)retainWeakReference NS_UNAVAILABLE;
@end
NSProxy和NSObject一样是NS_ROOT_CLASS,也就是根类NSProxy是实现@protocol NSObject,而不是继承@interface NSObjectNSProxy没有消息转发的第一步和第二步,直接到第三步,NSProxy也没有实现对应方法
实际上可当做NSProxy没有实现什么实例方法,虽然- (Class)class方法还是实现了。
这就使得
NSProxy非常单纯,干净,不像NSObject有很多分类,有很多方法不能转发NSProxy方法少,凡是NSProxy没有实现的方法都是可以转发的,也就是几乎所有的方法都可以转发NSProxy设计的代理类能够更加纯正
NSProxy的用途
- AOP
- 代理模式、Decorator模式,这里有一个简单的demo,可以参考
- 多继承,通过引用多个target模拟多继承。