首先展示一个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 NSObject
NSProxy
没有消息转发的第一步和第二步,直接到第三步,NSProxy
也没有实现对应方法
实际上可当做NSProxy
没有实现什么实例方法,虽然- (Class)class
方法还是实现了。
这就使得
NSProxy
非常单纯,干净,不像NSObject
有很多分类,有很多方法不能转发NSProxy
方法少,凡是NSProxy
没有实现的方法都是可以转发的,也就是几乎所有的方法都可以转发NSProxy
设计的代理类能够更加纯正
NSProxy的用途
- AOP
- Decorator模式,这里有一个简单的demo,可以参考
- 多继承,通过引用多个target模拟多继承。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END