NSRunloop简单细说(三)—— 定时器和端口

版本记录

版本号 时间
V1.0 2017.08.22

前言

NSRunloopOC Foundation框架中非常重要的一个类,很多时候我们会使用它,但是未必对其有深入的了解,接下来几篇我就会带着大家重新学习一下NSRunloop这个类,从简单到复杂,从基本到深化,我会一步步的走完。希望对大家有所帮助。感兴趣的可以看我上一篇。
1. NSRunloop简单细说(一)—— 整体了解
2. NSRunloop简单细说(二)—— 获取运行循环及其模式

一、- (void)addTimer:(NSTimer *)timer forMode:(NSRunLoopMode)mode;

这个方法我们经常用,其实就是将定时器加入到runloop中,才能开启定时器。

下面我们看一下参数:

  • timer :实例化的定时器对象。
  • 添加定时器的模式。 您可以指定自定义模式或使用运行循环模式Run Loop Modes中列出的其中一种模式。

下面看一个例子

- (void)demoAddTimer
{
    NSTimer *timer = [NSTimer timerWithTimeInterval:2.0 repeats:YES block:^(NSTimer * _Nonnull timer) {
        NSLog(@"A");
    }];
    [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
}

看一下输出结果

2017-08-23 12:20:57.584335+0800 JJOC[11019:5299493] A
2017-08-23 12:20:59.584386+0800 JJOC[11019:5299493] A
2017-08-23 12:21:01.584310+0800 JJOC[11019:5299493] A
2017-08-23 12:21:03.584310+0800 JJOC[11019:5299493] A
2017-08-23 12:21:05.584304+0800 JJOC[11019:5299493] A
2017-08-23 12:21:07.584378+0800 JJOC[11019:5299493] A

还有几点需要注意:

  • 可以向多种输入模式添加定时器。 当以指定模式运行时,接收器使计时器在预定日期到达时或之后触发。 触发时,定时器调用其相关联的处理程序例程,它是指定对象上的选择器。
  • 要从其安装的所有运行环路模式中删除定时器,请向定时器发送无效invalidate消息。
  • 这里定时器加入runloop的模式选择的是NSDefaultRunLoopMode,一般情况下是没有问题的,但是在一些情况下是有问题的,比如说滑动界面定时器停止等,这个解决方法就是更换模式为NSRunLoopCommonModes
  • 还有这个问题,我这里调用的这个方法是ios 10.0以后才有的,所以如果你适配8.0系统的话就不能用这个方法了,应该用+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;这个方法,还有个问题就是如果用上面那个block的方法还要注意循环引用的问题。

结论:这个很常用,大家需要谨记。


二、- (void)addPort:(NSPort *)aPort forMode:(NSRunLoopMode)mode;

该方法的作用就是:将端口作为输入源添加到运行循环的指定模式。其实就是往RunLoop的 Mode 中添加一个source1任务。

下面看一下参数:

  • aPort:要加入的端口。
  • mode:运行循环模式,还是那几种,前面已经说过了,这里就不多说了。

我们在AFNetworking中就看到了这个方法的使用,如下所示:

+ (void)networkRequestThreadEntryPoint:(id)__unused object 
{
    @autoreleasepool {
        [[NSThread currentThread] setName:@"AFNetworking"];
        NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
        [runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];
        [runLoop run];
    }
}

这里,开启了一个线程,同时开启runloop,并添加了一个port事件维系runloop 的运行,但是port并不发送时机的消息。这个线程是AFNetWorking用于将NSURLConection置于后台处理请求和回调的。不过现在NSURLConection已经被该框架所废弃了。大家知道这个用法和使用情况就可以了,其实编程思想比代码实现要重要的多。

下面还要注意:

  • 此方法使用接收器调度端口。 您可以将端口添加到多种输入模式。 当接收器以指定的模式运行时,它会将发往该端口的消息分派到端口的指定处理程序。

结论:思路很重要,需要大家思考。


三、- (void)removePort:(NSPort *)aPort forMode:(NSRunLoopMode)mode;

其实,只要你看过上面那个方法,那么这个方法的作用就很明显了,该方法的作用:从运行循环的指定输入模式中删除端口。这里就不多说参数什么的了,同上所示即可。

这里,还有几点需要注意:

  • 如果您将端口添加到多个输入模式,则必须分别从每个模式中删除它。

结论:同上。

参考文章

1. iOS RunLoop了解和使用

后记

未完,待续~~~~

NSRunloop简单细说(三)—— 定时器和端口_第1张图片

你可能感兴趣的:(NSRunloop简单细说(三)—— 定时器和端口)