Runloop的使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sacrifice123/article/details/51862058

一、什么runloop

从字面意思就是运行循环,他的作用体现在保持程序的持续运行,处理app中的各种事件(比如触摸事件、定时器事件、selector事件),节省cpu资源,提高程序性能:做事的时候做事,没事的时候睡眠。


我们的main函数里就启动了个runloop,所以程序运行起来后并不会马上退出,保持持续运行的状态。

runloop的逻辑处理:



二、runloop与线程

1、每条线程都有唯一的一个与之对应的runloop对象。

2、主线程的runloop已经自动创建好了,子线程的runloop需要主动创建。

3、runloop在第一次获取时创建,在线程结束时销毁。


三、获取runloop对象

lFoundation

[NSRunLoopcurrentRunLoop];// 获得当前线程的RunLoop对象

[NSRunLoopmainRunLoop];// 获得主线程的RunLoop对象

lCoreFoundation

CFRunLoopGetCurrent();// 获得当前线程的RunLoop对象

CFRunLoopGetMain();// 获得主线程的RunLoop对象


三、runloop相关类



1.CFRunLoopRef

2.CFRunLoopModeRef

1)代表runloop的运行模式,一个runloop包含若干个mode,每个mode又包含若干个source/timer/observer,但是每次启动时只能指定其中一个mode,这个mode被称为currentMode,如果需要切换mode,只能退出loop,在重新指定一个mode进入。这样做主要是为了分隔开不同组的Source/Timer/Observer,让其互不影响。

2)系统默认注册了5个Mode

a.  kCFRunLoopDefaultMode app默认的mode,通常主线程就是在这个mode下运行的
b.  UITrackingRunLoopMode 界面跟踪mode,用于scrollView追踪触摸滑动,保证界面滑动时不受其它mode影响
c. UIInitializationRunLoopMode:在刚启动app时进入的第一个mode,启动完成后就不在使用
d.  GSEventReceiveRunLoopMode : 接受系统事件的内部 Mode,通常用不到
e.  kCFRunLoopCommonModes : 这是一个占位用的Mode,不是一种真正的Mode(相当于一个标签,这个标签里可能含有几个mode,表示可以同时运行在几个mode下)

3.CFRunLoopSourceRef

CFRunLoopSourceRef是事件源(输入源)
Source0:非基于Port的
Source1:基于Port的

4.CFRunLoopTimerRef

5.CFRunLoopObserverRef

CFRunLoopObserverRef是观察者,能够监听RunLoop的状态改变
可以监听的时间点如下:


四、runloop的应用举例(线程常驻)

runloop有很多用处,我们规定某个操作在什么模式下进行,下面我们简单看看常驻线程的使用。

我们的线程在使用一次后就会消亡,并且无法重新启动,如果我们希望某个子线程不死,我们可以看如下代码实现:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.thread = [[NSThread alloc] initWithTarget:self selector:@selector(test) object:nil];
    [self.thread start];
}

- (void)test{
    
    
    NSLog(@"test");
    
    [[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
    [[NSRunLoop currentRunLoop] run];
}

-(void)test1{
    
    NSLog(@"----%@",[NSThread currentThread]);
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    [self performSelector:@selector(test1) onThread:self.thread withObject:nil waitUntilDone:NO];
    
}
@end

上面的代码重点就在这两行:(这两行代码使得线程不死,执行过一次不会消亡)

  [[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];

  [[NSRunLoop currentRunLoop] run];




猜你喜欢

转载自blog.csdn.net/sacrifice123/article/details/51862058