2018-07-26 GCD定时器的释放与程序崩溃的问题
2018-07-26 本文已影响840人
幸福晓杰2016
GCD定时器是dispatch_source_t类型的变量
@property (nonatomic,strong) dispatch_source_t timer;
/** 创建定时器对象
* para1: DISPATCH_SOURCE_TYPE_TIMER 为定时器类型
* para2-3: 中间两个参数对定时器无用
* para4: 最后为在什么调度队列中使用
*/
_gcdTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(0, 0));
/** 设置定时器
* para2: 任务开始时间
* para3: 任务的间隔
* para4: 可接受的误差时间,设置0即不允许出现误差
* Tips: 单位均为纳秒
*/
dispatch_source_set_timer(_gcdTimer, DISPATCH_TIME_NOW, 2.0 * NSEC_PER_SEC, 0.0 * NSEC_PER_SEC);
/** 设置定时器任务
* 可以通过block方式
* 也可以通过C函数方式
*/
dispatch_source_set_event_handler(_gcdTimer, ^{
static int gcdIdx = 0;
NSLog(@"GCD Method: %d", gcdIdx++);
NSLog(@"%@", [NSThread currentThread]);
});
// 启动任务,GCD计时器创建后需要手动启动
dispatch_resume(_gcdTimer);
// 定时器挂起
dispatch_suspend(_gcdTimer);
注意:dispatch_suspend 状态下直接释放定时器,会导致定时器崩溃。
初始状态,挂起状态,都不能直接调用
dispatch_source_cancel(timer);
调用就会导致app闪退。
建议:使用懒加载创建定时器,并且记录当timer 处于dispatch_suspend的状态。这些时候,只要在 调用dealloc 时判断下,已经调用过 dispatch_suspend 则再调用下 dispatch_resume后再cancel,然后再释放timer。
如果暂停后不进行重新启动 timer 的话,直接取消 timer会报错。一旦取消timer后就不能再重新运行 timer,否则就会崩溃,只能重建一个new timer。