iOS多线程编程(四)NSRunLoop初步概念以及NSTimer在NSThread中的使用

1.NSRunloop基本概念

@Run loops 是线程相关的基础框架的一部分.一个run loop就是一个事件处理的循环,用来不停的调度工作以及处理输入事件.

@线程的生命周期存在五个状态:新建,就绪,运行,阻塞,死亡

@NSRunLoop可以保持一个线程一直为活动状态,不会马上被销毁掉,在多线程中,子线程就不会被销毁


2.NSRunloop常用方法

+ (NSRunLoop *)currentRunLoop; //获得当前线程的run loop

+ (NSRunLoop *)mainRunLoop; //获得主线程的run loop

- (void)run; //进入处理事件循环,如果没有事件则立刻返回。注意:主线程上调用这个方法会导致无法返回(进入无限循环,虽然不会阻塞主线程),因为主线程一般总是会有事件处理。

- (void)runUntilDate:(NSDate *)limitDate; //同run方法,增加超时参数limitDate,避免进入无限循环。使用在UI线程(亦即主线程)上,可以达到暂停的效果。

- (BOOL)runMode:(NSString *)mode beforeDate:(NSDate *)limitDate; //等待消息处理,好比在PC终端窗口上等待键盘输入。一旦有合适事件(mode相当于定义了事件的类型)被处理了,则立刻返回;类同run方法,如果没有事件处理也立刻返回;有否事件处理由返回布尔值判断。同样limitDate为超时参数。

- (void)acceptInputForMode:(NSString *)mode beforeDate:(NSDate *)limitDate; //似乎和runMode:差不多(测试过是这种结果,但确定是否有其它特殊情况下的不同),没有BOOL返回值。

官网文档也提到run和runUntilDate:会以NSDefaultRunLoopMode参数调用runMode:来处理事件。

当程序运行后,主线程自动启动一个run loop,而多线程则需要手动来启动run loop。


3.定时器在多线程中的使用

@在多线程中使用定时器必须手动开启Runloop

@代码示例:

    [NSThread detachNewThreadSelector:@selector(onclick) toTarget:self withObject:nil];

- (void)onclick{

    // 子线程,需要手动加入一个释放池,来释放通过便利构造器创建的对象,主线程自动添加了

    @autoreleasepool {

        /**

         * 注意这2个初始化方法的区别

         * 实例方法创建的NSTimer,需要手动加入Runloop,便利构造器创建NSTimer,自动添加了

         NSTimer * timer = [NSTimer timerWithTimeInterval:0.5 target:self selector:@selector(ontime)  userInfo:nil repeats:YES];

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

         */

        [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(ontime) userInfo:nil repeats:YES];

        // 开启Runloop来使线程保持存活状态

        [[NSRunLoop currentRunLoop] run];

    }

}


4.调用主线程的run loop的各种方式

[[NSRunLoop mainRunLoop] run]; //主线程永远等待,但让出主线程时间片

[[NSRunLoop mainRunLooprunUntilDate:[NSDate distantFuture]]; //等同上面调用

[[NSRunLoop mainRunLooprunUntilDate:[NSDate date]]; //立即返回

[[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:10.0]]; //主线程等待,但让出主线程时间片,然后过10秒后返回

[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate: [NSDate distantFuture]]; //主线程等待,但让出主线程时间片;有事件到达就返回,比如点击UI等。

[[NSRunLoop mainRunLooprunMode:NSDefaultRunLoopMode beforeDate: [NSDate date]]; //立即返回

[[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate: [NSDate dateWithTimeIntervalSinceNow:10.0]]; //主线程等待,但让出主线程时间片;有事件到达就返回,如果没有则过10秒返回。






你可能感兴趣的:(NSThread,NSTimer,NSRunLoop)