什么是NSProxy
- NSProxy是和NSObject同级的一个类,可以说它是一个虚拟类,它只是实现了<NSObject>的协议;
- OC是单继承的语言,但是基于运行时的机制,却有一种方法让它来实现一下"伪多继承",就是利用NSProxy这个类;
- OC中的NSProxy类,填补了"多继承"这个空白;
- 通过继承NSProxy,并重写这两个方法以实现消息转发到另一个实例。
- (void)forwardInvocation:(NSInvocation *)anInvocation;
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel;
使用场景
场景:使用 NSTimer or CADisplayLink 定时器时,target是自己的情况下被强引用,即使使用weakself也无效
原理:使用Proxy类型占用target(self),使用方法实现消息转发,也就是说定时器不在占有target,而使用proxy类。(第三方框架YYKit中的YYWeakProxy类就是解决了定时器强引用问题)
示例代码:
_link = [CADisplayLink displayLinkWithTarget:[YYWeakProxy proxyWithTarget:self] selector:@selector(tick:)];
[_link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
- (void)initTimer {
YYWeakProxy *proxy = [YYWeakProxy proxyWithTarget:self];
_timer = [NSTimer timerWithTimeInterval:0.1 target:proxy selector:@selector(tick:) userInfo:nil repeats:YES];
}
- (void)tick:(NSTimer *)timer {...}
在YYWeakProxy中主要重写了下面两个方法
//重写NSProxy如下两个方法,在处理消息转发时,将消息转发给真正的Target处理
- (void)forwardInvocation:(NSInvocation *)invocation {
[invocation invokeWithTarget:self.target];
}
//
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
return [_target methodSignatureForSelector:selector];
}
注意
- NSProxy类是没有init方法的,也就是说如果我们要获得一个NSProxy的实例,代码只需要这样:
MyProxy *proxyInstance = [MyProxy alloc];
代码实例
我这边提供了一个 Demo,用于垃圾消息处理机制的实现。
百度网盘