美文网首页开发者联盟iOS Developer
iOS timer定时器正确使用方式

iOS timer定时器正确使用方式

作者: 72行代码 | 来源:发表于2019-07-11 11:33 被阅读47次

1. 初始化,添加定时器前先移除

[self.timer invalidate];
self.timer = nil;
self.timer = [NSTimer scheduledTimerWithTimeInterval:2.f target:self selector:@selector(lookforCard:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];

2. 释放timer

[self.timer invalidate];
self.timer = nil;

3. NSTimer不释放原因

  • 原因是 Timer 添加到 Runloop 的时候,会被 Runloop 强引用;然后 Timer 又会有一个对 Target 的强引用(也就是 self )

注意target参数的描述:
The object to which to send the message specified by aSelector when the timer fires. The timer maintains a strong reference to target until it (the timer) is invalidated.
注意:文档中写的很清楚,timer对target会有一个强引用,直到timer is invalidated。也就是说,在timer调用 invalidate方法之前,timer对target一直都有一个强引用。这也是为什么控制器的dealloc 方法不会被调用的原因。
方法的文档介绍:
The receiver retains aTimer. To remove a timer from all run loop modes on which it is installed, send an invalidate message to the timer.
也就是说,runLoop会对timer有强引用,因此,timer修饰符是weak,timer还是不能释放,timer的target也就不能释放。

4. 解决办法

  • viewWillDisappearviewDidDisappear中 invalidate
    这种方式是可以释放掉的,但如果我只是想在离开此页时要释放,进入下一页时不要释放,场景就不适用了
- (void)viewWillDisappear:(BOOL)animated
- (void)viewDidDisappear:(BOOL)animated
  • 添加一个NSTimer的分类,把target指给[NSTimer class],事件由加方法接收,然后把事件通过block传递出来
@interface NSTimer (Block)

+ (instancetype)scheduledTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void(^)(NSTimer *timer))block;

@end

@implementation NSTimer (Block)

+ (instancetype)scheduledTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void(^)(NSTimer *timer))block{
    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:interval target:self selector:@selector(trigger:) userInfo:[block copy] repeats:repeats];
    return timer;
}

+ (void)trigger:(NSTimer *)timer{
    void(^block)(NSTimer *timer) = [timer userInfo];
    if (block) {
        block(timer);
    }
}

@end
  • 使用示例
@interface SecondViewController ()

@property (nonatomic, strong) NSTimer *timer;

@end

@implementation SecondViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    __weak typeof(self) weakSelf = self;
    self.timer = [NSTimer scheduledTimerWithTimeInterval:0.5 repeats:YES block:^(NSTimer * _Nonnull timer) {
        [weakSelf doSomeThing];
    }];
    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}

- (void)dealloc {
    [self.timer invalidate];
}

@end

5. invalidate方法注意事项

invalidate方法的介绍:
(1)This method is the only way to remove a timer from an NSRunLoop object. The NSRunLoop object removes its strong reference to the timer, either just before the invalidate method returns or at some later point.
(2)You must send this message from the thread on which the timer was installed. If you send this message from another thread, the input source associated with the timer may not be removed from its run loop, which could prevent the thread from exiting properly.
两点:
(1)invalidate方法是唯一能从runloop中移除timer的方式,调用invalidate方法后,runloop会移除对timer的强引用
(2)timer的添加和timer的移除(invalidate)需要在同一个线程中,否则timer可能不能正确的移除,线程不能正确退出

附:我的博客地址

相关文章

  • iOS timer定时器正确使用方式

    1. 初始化,添加定时器前先移除 2. 释放timer 3. NSTimer不释放原因 原因是 Timer 添加到...

  • Crash拦截器 - NSTimer无法释放和内存泄漏之解除

    前言 在iOS开发中,我们使用定时器(timer)的几率很高,系统中最常用的方式有GCD中提供的timer接口和我...

  • GCD 定时器使用

    定时器有很多种实现方式,我们经常使用的定时器就是Timer了,然而 Timer 是基于线程的Runloop的,当执...

  • RxSwift中的Timer

    RxSwift中的Timer 我们在项目中经常会用到定时器,先来看下swift中使用定时器的几种方式: Timer...

  • iOS14开发-Timer

    定时器可以设置按固定周期执行某个操作。iOS 中主要有 3 种定时器,本文先讲解第一种 Timer。 使用 iOS...

  • [转]正确使用Go的Timer

    原文:正确使用GO的Timer我们总是会使用Timer去执行一些定时任务,最近在Go语言的定时器使用上面不小心踩到...

  • iOS 定时器耗电探究

    iOS开发中的几种定时器 iOS开发中定时器实现方式大致有三种,一种是Timer实现,一种是通过GCD自己创建,另...

  • 定时器 Timer

    定时器 Timer [toc] 定时器 Timer 的使用 Timer 类主要负责计划任务的功能,也就是在指定时间...

  • Java可自定义中断定时器的实现

    Java定时器的实现一般使用的是Timer和ScheduledExecutorService 使用Timer的时候...

  • 使用RxJava实现定时器功能

    使用RxJava实现定时器功能可以通过两种方式来实现,具体实现如下: 一、使用timer 操作符 二、使用使用in...

网友评论

    本文标题:iOS timer定时器正确使用方式

    本文链接:https://www.haomeiwen.com/subject/aknvxqtx.html