iOS NSProxy探究

什么是NSProxy

  • NSProxy是和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,用于垃圾消息处理机制的实现。
百度网盘

你可能感兴趣的:(iOS NSProxy探究)