【整理】NSTimer使用及注意事项

1、NSTimer的创建

// 创建一个定时器,但是么有添加到运行循环,我们需要在创建定时器后手动的调用 NSRunLoop 对象的 addTimer:forMode: 方法。

+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;

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

// 创建一个timer并把它指定到一个默认的runloop模式中,并且在 TimeInterval时间后 启动定时器

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo;

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

// 默认的初始化方法,(创建定时器后,手动添加到 运行循环,并且手动触发才会启动定时器) - (instancetype)initWithFireDate:(NSDate *)date interval:(NSTimeInterval)ti target:(id)t selector:(SEL)s userInfo:(nullable id)ui repeats:(BOOL)rep NS_DESIGNATED_INITIALIZER;

示例:

SvTestObject *testObject4 = [[SvTestObject alloc] init];

NSTimer *timer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:1] interval:1 target:testObject4 selector:@selector(timerAction:) userInfo:nil repeats:NO];

[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

2、NSTImer使用

// 启动 Timer 触发Target的方法调用但是并不会改变Timer的时间设置。 即 time没有到达到,Timer会立即启动调用方法且没有改变时间设置,当时间 time 到了的时候,Timer还是会调用方法。 - (void)fire;

// 启动定时器

timer.fireDate = [NSDate distantPast];

//停止定时器

timer.fireDate = [NSDate distantFuture];

// 开启

[time setFireDate:[NSDate distanPast]]

//关闭

[time setFireDate:[NSDate distantFunture]]

//继续。

[timer setFireDate:[NSDate date]];

// 停止 Timer ---> 唯一的方法将定时器从循环池中移除 - (void)invalidate;

3、NSTimer注意事项

3.1、NSTimer加到了RunLoop中但未能触发事件

原因主要有以下两个:

3.1.1、runloop是否运行

每一个线程都有它自己的runloop,程序的主线程会自动的使runloop生效,但对于我们自己新建的线程,它的runloop是不会自己运行起来,当我们需要使用它的runloop时,就得自己启动。

- (void)applicationDidBecomeActive:(UIApplication *)application { // NSThread 创建一个子线程 [NSThread detachNewThreadSelector:@selector(testTimerSheduleToRunloop1) toTarget:self withObject:nil]; } // 测试把timer加到不运行的runloop上的情况 - (void)testTimerSheduleToRunloop1 { NSLog(@"Test timer shedult to a non-running runloop"); SvTestObject *testObject4 = [[SvTestObject alloc] init]; NSTimer *timer = [[NSTimer alloc] initWithFireDate:[NSDate dateWithTimeIntervalSinceNow:1] interval:1 target:testObject4 selector:@selector(timerAction:) userInfo:nil repeats:NO]; [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; // 打开下面一行输出runloop的内容就可以看出,timer却是已经被添加进去 //NSLog(@"the thread‘s runloop: %@", [NSRunLoop currentRunLoop]); // 打开下面一行, 该线程的runloop就会运行起来,timer才会起作用 [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:3]]; NSLog(@"invoke release to testObject4"); } - (void)applicationWillResignActive:(UIApplication *)application { NSLog(@"SvTimerSample Will resign Avtive!"); }

3.1.2、mode是否正确

run loop在运行时一般有两个mode,一个defaultmode,一个trackingmode。同一线程的runloop在运行的时候,任意时刻只能处于一种mode。所以只能当程序处于这种mode的时候,timer才能得到触发事件的机会。

正常情况下run loop使用defaultmode,scheduled生成的timer会默认添加到defaultmode中,当我们互动scrollview时,run loop切换到trackingmode运行,于是我们发现定时器失效了。为了使定时器在我们滑动scrollview时也能正常运行,我们需要确保defaultmode和trackingmode里都添加了我们生成的timer。如:

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:_timeInterval target:self selector:@selector(addone) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode];

或者:

NSTimer *timer = [NSTimer timerWithTimeInterval:_timeInterval target:self selector:@selector(addone) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] addTimer:timer forMode:UITrackingRunLoopMode]; [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];

或者

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:_timeInterval target:self selector:@selector(addone) userInfo:nil repeats:YES];

[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];

综上: 要让timer生效,必须保证该线程的runloop已启动,而且其运行的runloopmode也要匹配。

3.2、

使用NSTimer时,timer会保持对target和userInfo参数的强引用。只有当调取了NSTimer的invalidate方法时,NSTimer才会释放target和userInfo。

生成timer的方法中如果repeats参数为NO,则定时器触发后会自动调取invalidate方法。如果repeats参数为YES,则需要程序员手动调取invalidate方法才能释放timer对target和userIfo的强引用。

在使用repeats参数为YES的定时器时,如果在使用完定时器时后没有调取invalidate方法,导致target和userInfo没有被释放,则可能会形成循环引用情况,从而影响内存释放。

//取消定时器

[timer invalidate]; // 将定时器从运行循环中移除

timer = nil; // 销毁定时器 ---》 这样可以避免控制器不死

时间: 2024-12-13 05:21:22

【整理】NSTimer使用及注意事项的相关文章

Web 安全开发注意事项

一.背景 最近开发公司的WEB项目,商密技术研究部领导推出了一套测试规范,规范中包括web端安全测试扫描,扫描结果不尽如人意,因此搜集及整理如下web安全开发事项. 二.编码安全策略 简述:不要相信任何来自客户端提交的数据,比如URL和参数,HTTP头部.javascript或者其他嵌入代码提交的数据.对客户端提交的数据需要经过过滤或者转义,然后再进行处理. 1.客户端提交数据验证 a.合法性校验 不可信数据的合法性校验包括:数据类型校验如字符.数字.日期等特征;数据范围;数据长度等. b.防范

Android文件存储详细完整示例

MainActivity如下: package cc.cv; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import android.os.Bundl

Android之Android WebView常见问题及解决方案汇总

如有转载,请声明出处: 时之沙: http://blog.csdn.net/t12x3456 Android WebView常见问题解决方案汇总: 就目前而言,如何应对版本的频繁更新呢,又如何灵活多变地展示我们的界面呢,这又涉及到了web app与native app之间孰优孰劣的争论. 于是乎,一种混合型的app诞生了,灵活多变的部分,如淘宝商城首页的活动页面,一集凡客诚品中我们都可以见到web 页面与native页面的混合,既利用了web app的灵活易更新,也借助了native app本身

中央针对“红顶中介”,审批部门利益输送整顿

近年来,一些被称为“二政府”的“红顶中介”及其催生的乱象受到高度关注.国务院审改办负责人王峰昨天在国务院方针例行吹风会上表明,国务院已经过相关文件,中心将采取6项具体措施整理标准国务院部分行政批阅中介效劳,直指广受诟病的“红顶中介”.韩国赌场 >>措施 切断利益关联禁止指定中介 国务院审议经过的<通知>提出了整理标准的具体措施和要求,主要有6项内容: 1.整理事项 关于中介效劳事项多.耗时长.设定不标准的问题,提出除依法设定的外一律不再作为批阅的受理条件,能够经过加强事中事后监管解

Meme游戏服务器开发日记(二)绕过GIL启动多线程Python环境

说道Python和多线程,很容易想到GIL,GIL意味着只要是用Python做的多线程程序,就无法利用多个CPU. 经过一些失败的尝试后,我也一度认为GIL是无解的.我们甚至把注意力转向了IronPython等无锁Python,但是实际上那样问题可能更多,比如我们不熟悉mono,mono也没达到完全成熟的程度. 直到skynet的QQ群里一位朋友介绍了另一种加载so的方式,事情才有了180度的变化. 方法如下: 1.编译Python源码,编译时加上参数--enable-shared,编译成so动

一个程序员的时间管理

原文地址:http://www.myexception.cn/other/1391133.html 如果每天都有86400元进入你的银行户头,而你必须当天用光,你会如何运用这笔钱? 天下真有这样的好事吗? 是的,而且这种好事每天都在发生着,你真的有这样一个户头,那就是“时间”.每天每一个人都会有新的86400秒进账,而这86400秒的价值要远远的大于86400元.那么,面对这样的一大笔财富.你打算怎样利用它们呢? 其实吧,我并不知道你是如何利用它们,但我知道我自己是如何利用的,下面把我的一些时间

Android WebView常见问题汇总

如有转载,请声明出处: 时之沙: http://blog.csdn.net/t12x3456 Android WebView常见问题解决方案汇总: 就目前而言,如何应对版本的频繁更新呢,又如何灵活多变地展示我们的界面呢,这又涉及到了web app与native app之间孰优孰劣的争论. 于是乎,一种混合型的app诞生了,灵活多变的部分,如淘宝商城首页的活动页面,一集凡客诚品中我们都可以见到web 页面与native页面的混合,既利用了web app的灵活易更新,也借助了native app本身

Android WebView常见问题及解决方案汇总

Android WebView常见问题解决方案汇总: 就目前而言,如何应对版本的频繁更新呢,又如何灵活多变地展示我们的界面呢,这又涉及到了web app与native app之间孰优孰劣的争论. 于是乎,一种混合型的app诞生了,灵活多变的部分,如淘宝商城首页的活动页面,一集凡客诚品中我们都可以见到web 页面与native页面的混合,既利用了web app的灵活易更新,也借助了native app本身的效率.当然,就会用到webview这样的一个控件,这里,我把自己使用过程中遇到的一些问题整理

[工具]Microsoft To-Do,简约还是简陋?

1. 简介 微软收购奇妙清单后,由奇妙清单的原班人马打造了一个全新的待办事项应用,就叫"To-Do"(简单粗暴,好像新浪微博直接就叫"微博"的感觉).这个应该刚推出我就从奇妙清单转到To-Do上,使用一段时间后感觉比奇妙清单好用一些.主要功能上感觉没什么区别,一来是因为由原班人马打造,UI感觉相似:二来是因为我本来就不用奇妙清单上有的,而在To-Do上被砍掉的各种高级功能. 官方网站 2. 如何使用 To-Do主页或应用商店就已经把所有功能介绍得清清楚楚. Micr