OC-Timer定时器内存循环引用 解析

2019-02-18  本文已影响12人  小小小蚍蜉

NSTimer经常会引起循环引用,以下是几种解决方案:

一:使用block的NSTimer,如下:

    __weak typeof(self) weakSelf = self;

    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 repeats:YES block:^(NSTimer * _Nonnull timer) {

        [weakSelftimerTest];

    }];

二:使用代理对象(NSProxy),自定义一个子类WPProxy继承于NSProxy。代码如下:

 创建timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:[WPProxy proxyWithTarget:self] selector:@selector(xxx) userInfo:nil repeats:YES];

在创建的子类.m文件中实现以下方法:

+ (instancetype)proxyWithTarget:(id)target

{

    // NSProxy对象不需要调用init,因为它本来就没有init方法

    WPProxy*proxy = [WPProxy alloc];

    proxy.target= target; // target在点.h文件中定义,weak修饰属性

    returnproxy;

}

- (NSMethodSignature*)methodSignatureForSelector:(SEL)sel

{

    return [self.target methodSignatureForSelector:sel];

}

- (void)forwardInvocation:(NSInvocation*)invocation

{

    [invocationinvokeWithTarget:self.target];

}

三 NSTimer依赖于RunLoop,如果RunLoop的任务过于繁重,可能会导致NSTimer不准时,GCD的定时器会更加准时。代码实现如下:

{

dispatch_queue_t queue = dispatch_queue_create("timer", DISPATCH_QUEUE_SERIAL);

    // 创建定时器

    dispatch_source_ttimer =dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,0,0, queue);

    dispatch_source_set_timer(timer,

                              dispatch_time(DISPATCH_TIME_NOW,2 *NSEC_PER_SEC),

                              1.0 *NSEC_PER_SEC,0);

    // 设置回调

    dispatch_source_set_event_handler(timer, ^{

        NSLog(@"1111");

    });

    // 启动定时器

    dispatch_resume(timer);

}

上一篇下一篇

猜你喜欢

热点阅读