菜单导航

GCD实现多个定时器,完美避过NSTimer的三大缺陷(Ru

作者: 唐山便民助手 发布时间: 2019年12月20日 08:01:43

ios开发 nstimer暂停_nstimer_ios nstimer

定时器在我们每个人做的iOS项目里面必不可少,如登录页面倒计时、支付期限倒计时等等,一般来说使用NSTimer创建定时器:

+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo; + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;

But 使用NSTimer需要注意一下几点:

1、必须保证有一个活跃的RunLoop。

系统框架提供了几种创建NSTimer的方法,其中以scheduled开头的方法会自动把timer加入当前RunLoop,到了设定时间就会触发selector方法,而没有scheduled开头的方法则需要手动添加timer到一个RunLoop中才会有效。程序启动时,会默认启动主线程的RunLoop并在程序运行期内有效,所以把timer放入主线程时不需要启动RunLoop,但现实开发中主线程更多的是处理UI事物,把耗时且耗能的操作放在子线程中,这就需要将子线程的RunLoop激活。

我们不难知道RunLoop在运行时一般有两个:NSDefaultRunLoopMode、NSEventTrackingRunLoopMode,scheduled生成的timer会默认添加到NSDefaultRunLoopMode,当某些UI事件发生时,如页面滑动RunLoop切换到NSEventTrackingRunLoopMode运行,我们会发现定时器失效,为了解决timer失效的问题,我们需要在scheduled一个定时器的时候,设置它的运行模式为:

nstimer_ios nstimer_ios开发 nstimer暂停

[[NSRunLoop currentRunLoop] addTimer:self.progressTimer forMode:NSRunLoopCommonModes];

注意:NSRunLoopCommonModes并不是一种正在存在的运行状态,这个模式等效于NSDefaultRunLoopMode和NSEventTrackingRunLoopMode的结合,相当于它标记了timer可以在这两种模式下都有效。

2.NSTimer的创建与撤销必须在同一个线程操作,不能跨越线程操作。

3.存在内存泄漏的风险(这个问题需要引起重视)

scheduledTimerWithTimeInterval方法将target设为A对象时,A对象会被这个timer所持有,也就是会被retain一次,timer又会被当前的runloop所持有。使用NSTimer时,timer会保持对target和userInfo参数的强引用。只有当调取了NSTimer的invalidate方法时,NSTimer才会释放target和userInfo。生成timer的方法中如果repeats参数为NO,则定时器触发后会自动调取invalidate方法。如果repeats参数为YES,则需要手动调取invalidate方法才能释放timer对target和userIfo的强引用。

- (void)cancel{ [_timer invalidate]; _timer = nil; }

ios开发 nstimer暂停_nstimer_ios nstimer

这里要特别注意的一点是,按照各种资料显示,我们在销毁或者释放对象时,大部分都是在dealloc方法中,然后我们高高兴兴的在dealloc里写上

- (void)dealloc{ [self cancel]; }

以为这样就可以释放timer了,不幸的是,dealloc方法永远不会被调用。因为timer的引用,对象A的引用计数永远不会降到0,这时如果不调用cancel,对象X将永远无法释放,造成内存泄露。所以我建议在使用定时器的事件完成后立即将timer进行cancel,如果是比较长时间的定时器,可以在页面消失事件中调用,如:

- (void)viewWillDisappear:(BOOL)animated{ [super viewWillDisappear:animated]; [self cancel]; }

看到这里,你会不会发现使用NSTimer实现定时器这么麻烦,又是RunLoop,又是线程的,一会儿还得考虑内存泄露,So , 如果在一个页面需要同时显示多个计时器的时候,NSTimer简直就是灾难了。那么有没有高逼格的办法实现呢?答案就是GCD! 以下5点是使用dispatch_source_t创建timer的主要知识点:

1.获取全局子线程队列

ios nstimer_nstimer_ios开发 nstimer暂停

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

2.创建timer添加到队列中

dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);

3.设置首次执行事件、执行间隔和精确度

dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, interval * NSEC_PER_SEC), interval * NSEC_PER_SEC, 0.1 * NSEC_PER_SEC);

4.处理事件block

你喜欢吗更多>
我们颐和的三个方向:【颐和果园全国总代+V:972925955】 第一,帮助果农,助农销售 第二,让大家吃到实惠新鲜的水果。 第三,你也有一份长久稳定的事业。 经常会有客人问我:你
2019年12月19日 02:56:56  唐山便民助手
对视频进行分类是一个活跃的研究领域,因为处理这种类型的问题需要大量的数据。内存需求经常达到现代GPU的极限,可能需要在多台机器上进行分布式的训练。 目前学者们正在探索
2019年12月17日 00:40:25  唐山便民助手
现在房租这么贵,而大家通过手机点餐的数量越来越多,只需要有好手艺,比如会做排骨饭、黄焖鸡套饭、炒饭等等,就能自己建一个网上饭店,自己做老板。 没有实体店如何做外卖
2019年12月16日 23:43:14  唐山便民助手
demo中的group.js 中,获取到的是当前登陆账号已加入的群组,咱们做的是聊天室功能,所以需要有一个加入的操作,找roomlist.js 中找到 into_room: function (event),然后填写加入聊天室的方法
2019年12月16日 20:45:21  唐山便民助手

随机推荐更多>
简短提示:本文标题视力下降快,这“3种食物”要少吃,你的近视可能是“吃”出来的。 摘要:说起视力问题 , 很多人觉得长期用眼才会让眼睛变得干涩、红肿 , 视力才会因此降低
2月26日,记者从我市排水总公司获悉,1000多公里的雨污管线清掏疏通工作又开始了。 据介绍,市排水总公司管道管理所今年早下手,提前启动清掏疏通工作,重点疏通城区生活、生产
北京2017群租房新规定_ 北京群租房 新规全文_北京对群租房有何新规定群租房由于租金便宜而受到不少北漂人员的青睐,但由于人员的聚集给社会治安带来了不少隐患 北京群租房 ,近
我们通过2017年汽车行业分析可知全国汽车保有量达2.17亿辆,与2016年相比,全年增加2304万辆,增长11.85%。 农村+三四五线城市市场开拓,挖掘销量新增长空间 共享洗车 ,三四线小城市
近日,唐山市组织召开2017年度全市伊斯兰教阿訇年终述职评议会,每清真寺驻寺阿訇就年度岗位履职情况进行述职。全市驻寺备案阿訇和市伊协秘书长以上人员30余人参加会议。 年终
戴手表是一种流行趋势,许多年轻人喜欢戴手表。比起传统手表,年轻人更喜欢时尚手表而不是他们的需求。首先,勒未定谈到了 七个星期五 的设计理念:设计灵感来自CRT电视,机器
为加强生态保护,强化生态治理,发展绿色经济,提升民生福祉,连日来,博野县紧紧围绕年度环保目标任务,大力实施“蓝天、碧水、净土、风暴”四项行动,推进生态环境持续改
核心提示 伍仁桥村,位于安国市伍仁桥镇,历史悠久,源远流长,素有“祁南雄镇”之称。从东汉时期的屯兵之地,到唐宋元时期的御道,再到明朝的驿站……这里曾有众多名胜古迹
近日,唐山移动联合顺平县教育局、河南校讯通教育科技有限公司在顺平实验中学报告厅隆重召开了“众享在线课程交流会”,顺平教育局相关领导,全县80多名数学教师及学生代表,
情牵老乡冷暖,心系扶贫责任。4月25日,市人大常委会机关干部和部分人大代表一行80余人到唐县黄金峪村、葛公村慰问贫困户,逐人逐户了解生活现状,一对一送上脱贫良策。 “小
热门标签更多>