1. 今天在开发的时候,遇到NSTimer无效、所以也到网上找了一些资料,看看究竟怎么回事儿、
再次也做一次分享、方便有需要的朋友。
1. NSTimer是做什么的?
1.简单的理解就是一个定时器,在开发过程中,特定时间或者周期性去执行一个任务。
一次性
[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(createSoapClient) userInfo:nil repeats:NO];
周期性
[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(createSoapClient) userInfo:nil repeats:YES];
如果使用重复的NSTimer
一定要有对应的invalidate
,否则Timer
会一直存在。
NSTimer
会对target
对象进行一次retain
,所以我们要注意target
对象的生命周期。
2. NSTimer 为什么失效? NStimer与runloop的关系?
runloop是什么 ?
runloop是事件接收和分发机制的一个实现。
Run loops是线程的基础架构部分。一个run loop就是一个事件处理循环,用来不停的调配工作以及处理输入事件。使用run loop的目的是使你的线程在有工作的时候工作,没有的时候休眠。
NSTimer *timer = [[NSTimer alloc]initWithFireDate:[NSDate dateWithTimeInterval:10 sinceDate:[NSDate date]] interval:1 target:self selector:@selector(createSoapClient) userInfo:nil repeats:YES];
这儿的原因就是没有吧这个NSTimer加入到runloop中去,所以没有执行。 上面写的代码为什么就可以了, 我们前面做演示的代码创建的
NSTimer
会默认为我们添加到
Runloop
的
NSDefaultRunLoopMode
中,而且由于是在主线程中,所以
Runloop
是开启的,不需要我们手动打开,所以是可以执行的。 正确的代码如下
NSRunLoop *loop = [NSRunLoop currentRunLoop];
NSTimer *timer = [[NSTimer alloc]initWithFireDate:[NSDate dateWithTimeInterval:10 sinceDate:[NSDate date]] interval:1 target:self selector:@selector(createSoapClient) userInfo:nil repeats:YES];
[loop addTimer:timer forMode:NSDefaultRunLoopMode];
[loop run];
在iOS 多线程中,每一个线程都有一个
Runloop
,但是只有主线程的
Runloop
默认是打开的,其他子线程也就是我们创建的线程的
Runloop
默认是关闭的,需要我们手动运行。
我们可以通过
[NSRunLoop currentRunLoop]
来获得当前线程的
Runloop
,并且调用
[runloop addTimer:timer forMode:NSDefaultRunLoopMode]
方法将定时器添加到
Runloop
中,最后一定不要忘记调用
Runloop
的
run
方法将当前
Runloop
开启,否则
NSTimer
永远也不会运行。