博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
GCD计时器替换NSTimer
阅读量:6272 次
发布时间:2019-06-22

本文共 3798 字,大约阅读时间需要 12 分钟。

1.问题描述

使用NSTimer,repeats参数传YES的时候,可能导致Timer不能及时释放,如:

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:1.0                                                  target:weakSelf                                                selector:@selector(timerTick:)                                                userInfo:nil                                                 repeats:YES];复制代码

此时,假如持有timer的是UIView对象self,self不能调用Dealloc释放。所以,在需要释放self的时候,需要先手动销毁计时器timer。

- (void)dealloc {    //即使将timer的target设置为weakSelf,也不会进入此方法,进行释放    [self destroyTimer];}复制代码

2.使用GCD计时器替换NSTimer可以解决以上问题

头文件

#import 
@interface TTTimer : NSObject/** 计时器总时长 */@property (nonatomic, assign) NSInteger duration;/** 钟摆间隔 */@property (nonatomic, assign) NSInteger tickInterval;/** 倒计时 */- (void)tickDownProgress:(void(^)(void))progress;- (void)tickDownCompletion:(void(^)(void))completion;- (void)suspend;- (void)resume;- (void)destroy;@end复制代码

实现文件

#import "TTTimer.h"@interface TTTimer () {        BOOL _isTickComplete;    BOOL _isSuspend;}@property (nonatomic, strong) dispatch_source_t timer;@end@implementation TTTimer- (instancetype)init {        if (self = [super init]) {        _duration = 0;        _tickInterval = 0;        _isTickComplete = NO;        _isSuspend = YES;    }        return self;}- (void)tickDownProgress:(void(^)(void))progress {        if(self.duration == 0) return;        if (!self.timer) {        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);        self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);        dispatch_source_set_timer(self.timer,                                  dispatch_walltime(NULL, 0),                                  self.tickInterval * NSEC_PER_SEC,                                  0);        dispatch_source_set_event_handler(self.timer, ^{            if (progress) {                dispatch_async(dispatch_get_main_queue(), ^{                    progress();                });            }        });                [self resume];    }}- (void)tickDownCompletion:(void(^)(void))completion {        if(self.duration == 0) return;        __block NSInteger timeOut = self.duration;    if (!self.timer) {        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);        self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);        dispatch_source_set_timer(self.timer,                                  dispatch_walltime(NULL, 0),                                  self.tickInterval * NSEC_PER_SEC,                                  0);        dispatch_source_set_event_handler(self.timer, ^{            if (timeOut <= 0) {                [self destroy];                if(completion) {                    dispatch_async(dispatch_get_main_queue(), ^{                        completion();                    });                }                                _isTickComplete = YES;            }else {                timeOut = timeOut - self.tickInterval;            }        });                [self resume];    }}- (void)suspend {        if (self.timer && !_isSuspend) {        dispatch_suspend(self.timer);        _isSuspend = YES;    }}- (void)resume {        if (self.timer && _isSuspend) {        dispatch_resume(self.timer);        _isSuspend = NO;    }}- (void)destroy {        if (self.timer) {        if (!_isTickComplete) {            [self resume];        }                dispatch_source_cancel(self.timer);        self.timer = nil;    }}@end复制代码
  1. 避免Block循环引用
- (void)setupTimer {        __weak typeof(self) weakSelf = self;    self.toolTimer = [[TTTimer alloc] init];    self.toolTimer.tickInterval = 1;    self.toolTimer.duration = 5;    [self.toolTimer tickDownCompletion:^{        [weakSelf doSomething];    }];}复制代码

转载地址:http://amlpa.baihongyu.com/

你可能感兴趣的文章
正文提取算法
查看>>
轻松学PHP
查看>>
Android android.support.design包
查看>>
CheckBox:屏蔽setChecked方法对OnCheckedChangeListener的影
查看>>
java线程池
查看>>
UI面试内容
查看>>
Linux之RPM详解
查看>>
Windows Azure 常见问题及测试题
查看>>
android-genymotion模拟器使用
查看>>
phpstudy2018 windows 下搭建https 环境
查看>>
使用guava来进行优雅的函数式编程
查看>>
C++ - 判断文件夹(folder)是否存在(exist)
查看>>
小程序-修改多级数据
查看>>
不管10天20天这都是个悲剧何必呢
查看>>
建立简单的FTP服务器
查看>>
OWA登录页面显示为英文而不是中文
查看>>
711B - 人性的弱点
查看>>
PHP使用Memached实现Session储存
查看>>
IDEA debug调试技巧
查看>>
非常好的Python学习资源收集整理
查看>>