ios实用开发技巧人猿星球iOS开发

NSTimer,CADisplayLink内存泄漏

2018-09-11  本文已影响6人  _Andy_

今天在Q群 问了些面试题,有一个 NSTimer 怎么处理内存泄漏的问题,

- (void)dealloc{
      [_timer invalidate];
    NSLog(@"释放%s",__func__);
}

但是deallco方法根本不会执行,除非我们在ViewController 添加事件 提前进行 [_timer invalidate]; ViewController才会执行dealloc, 当我们想让Timer一直运行直到ViewController被dealloc的时候才被释放,这就不行了。

YYWeakProxy

@property (nonatomic, weak, readonly) id target;

+ (instancetype)proxyWithTarget:(id)target {
    return [[YYWeakProxy alloc] initWithTarget:target];
}
//将消息接收对象改为 _target
- (id)forwardingTargetForSelector:(SEL)selector {
    return _target;
}
//self 对 target 是弱引用,一旦 target 被释放将调用下面两个方法,如果不实现的话会 crash
- (void)forwardInvocation:(NSInvocation *)invocation {
    void *null = NULL;
    [invocation setReturnValue:&null];
}

- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
    return [NSObject instanceMethodSignatureForSelector:@selector(init)];
}

YYWeakProxy 继承自 NSProxy,是 Foundation 框架两大基类之一,实现了 NSObject 协议。
NSProxy 做为消息转发的抽象代理类,没有 init 方法,子类必须实现 initWithXXX: forwardInvocation: 和 methodSignatureForSelector: 方法)。
当不能识别方法时候,就会调用forwardingTargetForSelector方法,在这个方法中,我们可以将不能识别的传递给其它对象处理
需要重载methodSignatureForSelector和forwardInvocation的,为什么呢?因为_target是弱引用的,所以当_target可能释放了,当它被释放了的情况下,那么forwardingTargetForSelector就是返回nil了.然后methodSignatureForSelector和forwardInvocation没实现的话,就直接crash了!!!
这也是为什么这两个方法中是随便写的 ,而没有将消息转发给其他对象的操作

//NSTimer,
 _timer = [NSTimer timerWithTimeInterval:1.0
                                              target:[YYWeakProxy proxyWithTarget:self]
                                            selector:@selector(timerClick:)
                                            userInfo:nil
                                             repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:_longPressTimer forMode:NSRunLoopCommonModes];

//CADisplayLink
   _link = [CADisplayLink displayLinkWithTarget:[YYWeakProxy proxyWithTarget:self] selector:@selector(linkClick:)];
    [_link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];

参考:
IOS定时器操作和NSTimer的各种坑
NSTimer和实现弱引用的timer的方式

上一篇 下一篇

猜你喜欢

热点阅读