iOS RunLoop总结

一.RunLoop的基本概念

RunLoop是oc底层的一个机制,是运行循环,死循环。当应用程序需要的时候跑起来,不需要的时候处于休眠状态,这种特性可以充分提高CPU资源,提高程序的性能。

NSRunLoop三种模式:

  1. NSRunLoopCommonModes:占位模式(并不是runloop的一种模式) 无论是否操作UI都处理timer事件
  2. NSDefaultRunLoopMode:默认模式 当不操作UI的时候才 苹果建议处理timer事件 网络事件
  3. UITrackingRunLoopMode:ui 模式 当操作ui的时候才处理timer事件 苹果建议处理ui事件
二.RunLoop的作用

RunLoop常常和线程结合在一起讨论

1.保证线程不退出(RunLoop一旦启动 线程就不会退出)

一般来讲,一个线程一次只能执行一个任务,执行完成后线程就会退出。但是有时候我们需要线程能够一直“待命”随时处理事件而不退出,这就需要一个机制来完成这样的任务。

2.负责监听所有的事件 iOS中的触摸/时钟/网络事件

比如说时钟事件 创建timer 有两种方式 一种是

(1). 添加到默认模式 将RunLoop封装起来

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

(2).另一种是创建timer后手动开启runloop

_finished = NO;
_tasks = [NSMutableArray array];
//创建的子线程
      NSThread *thread = [[NSThread alloc] initWithBlock:^{
      NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
//将timer加到当前runloop中 但是执行一次后 线程被释放
      [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
//让当前线程的runloop跑起来 监听事件 保证线程不被释放 如果没有这段代码 则执行一次后线程会被释放 一条线程要想保住 必须让runloop启动 是一个死循环
      [[NSRunLoop currentRunLoop] run];
    while (!_finished) {
//让runloop跑0.00001秒 跑起来有事情处理事情 没事情就沉睡
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.0001]];
    }
//有[[NSRunLoop currentRunLoop] run];则不会打印
     NSLog(@"我来了");
}];
//启动线程
    [thread start];
//强引用使thread对象不会被释放 保住的是thread(一个oc对象) 但没有保住线程 线程是由CPU来调用的和oc对象没有丝毫关系 oc对象只是提供了一个接口来操作线程 线程的释放与oc没关系 只能runloop来保住线程
     self.thread = thread;

在这里如果不手动开启runloop 即[[NSRunLoop currentRunLoop] run]则线程执行一次后就直接被释放 如果声明一个强引用只能使thread对象不会被释放 保住的是thread(一个oc对象) 但没有保住线程 线程是由CPU来调用的和oc对象没有丝毫关系 oc对象只是提供了一个接口来操作线程 线程的释放与oc没关系 只能runloop来保住线程。

3.负责绘制UI
三.RunLoop与线程的关系

RunLoop,最重要的作用,也就是用来管理线程的。可以说,没有线程,也就没有RunLoop的存在必要。

主线程和子线程:

1.没有任何分别
2.只不过主线程的RunLoop是由操作系统来开启的 子线程的RunLoop是由开发者手动开启的。
其实在我们每次建立项目的时候,就已经使用上了RunLoop。
在程序的启动入口main函数中有这样一段熟悉的代码:

参数解释:
        argc, argv:则是由操作系统传给app的所以这两个参数无需管理
        nil:默认是字符串@“UIApplication” 当然也可以自定义一个类继承UIApplication 
        NSStringFromClass([AppDelegate class]:字符串 
        应用程序的main函数是由操作系统启动的,操作系统开启了一条主线程(对应用程序来说是主线程 但对于操作系统来说是子线程)此内部已经开启了RunLoop死循环,所以app的主线程是常驻线程,在自动释放池中不会被释放从而保证应用程序不会退出。

int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

你可能感兴趣的:(iOS RunLoop总结)