NSTimer解除循环引用

Posted gavanwanggw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NSTimer解除循环引用相关的知识,希望对你有一定的参考价值。

NSTimer作为一个经常使用的类,却有一个最大的弊病,就是会强引用target。造成调用timer很麻烦。稍有不慎就造成内存泄漏。

下面就是为解决问题做的封装。

直接上代码:


#import <Foundation/Foundation.h>


@interface LZLTimer : NSObject


-(void)startTimerInterval:(NSTimeInterval)ti target:aTarget selector:(SEL)selector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;


@end



#import "LZLTimer.h"

@interface LZLWeakTimerTarget : NSObject


@property (nonatomic,weak) id target;

@property (nonatomic,assign) SEL selector;


- (void)timerDidFire:(NSTimer *)timer;


@end


@implementation LZLWeakTimerTarget


- (void)timerDidFire:(NSTimer *)timer {

    if(_target) {

        //消除arc警告

        IMP imp = [_target methodForSelector:_selector];

        if ([NSStringFromSelector(_selector) hasSuffix:@":"]) {

            void (*func)(id, SEL, id) = (void *)imp;

            func(_target, _selector, timer);

        }else {

            void (*func)(id, SEL) = (void *)imp;

            func(_target, _selector);

        }

    } else {

        [timer invalidate];

    }

}


@end


@interface LZLTimer () {

    NSTimer *_timer;

}


@end


@implementation LZLTimer


-(void)dealloc {

    if (_timer!=nil) {

        [_timer invalidate];

        _timer = nil;

    }

}


-(void)startTimerInterval:(NSTimeInterval)ti target:aTarget selector:(SEL)selector userInfo:(id)userInfo repeats:(BOOL)yesOrNo {

    if (nil == _timer) {

        WMWeakTimerTarget *weakTarget = [[WMWeakTimerTarget alloc] init];

        weakTarget.target = aTarget;

        weakTarget.selector = selector;


        _timer = [NSTimer scheduledTimerWithTimeInterval:ti target:weakTarget selector:@selector(timerDidFire:) userInfo:userInfo repeats:yesOrNo];

    }

}


@end


以上是关于NSTimer解除循环引用的主要内容,如果未能解决你的问题,请参考以下文章

解决NSTimer或CADisplayLink计时器造成的循环引用问题。

iOS NSTimer 的循环引用问题

iOS NSTimer 的循环引用问题

常见的出现内存循环引用的场景有哪些?

循环引用不释放控制器

【OC梳理】循环引用及解决