RunLoop:iOS线程中的循环机制

作者:菠萝爱吃肉2024.01.18 10:19浏览量:6

简介:RunLoop是iOS应用于线程中的一种循环机制,保持程序的持续运行,处理App中的各种事件,节约CPU资源,提高程序性能。本文将详细介绍RunLoop的基本概念、作用、创建与使用,以及需要注意的事项。

RunLoop是iOS中用于线程的一种循环机制,它在程序运行过程中循环执行一些任务。如果没有RunLoop,程序运行结束后就会立即退出。在Objective-C中,主函数会自动为我们创建RunLoop,因此程序不会立即退出,而是保持运行状态,监听用户的相关操作。
RunLoop的基本作用是保持程序的持续运行,并处理应用程序中的各种事件,如触摸事件、定时器事件等。通过RunLoop,程序可以在需要时执行任务,并在空闲时进入休眠状态,从而节约CPU资源并提高程序性能。RunLoop使程序在运行过程中按需响应事件,而不是持续占用CPU资源。
要使用RunLoop,首先需要获取或创建一个RunLoop对象。系统本身没有提供创建RunLoop的API,但可以通过currentRunLoop获取当前线程的RunLoop对象。主线程本身就存在一个RunLoop,而子线程的RunLoop需要手动开启。如果子线程没有开启RunLoop,就无法监听到输入源与定时源。
创建RunLoop对象可以通过以下方式实现:

  1. NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; 获取当前线程的RunLoop对象。
  2. NSRunLoop *runLoop = [NSRunLoop mainRunLoop]; 获取主线程的RunLoop对象。
  3. CFRunLoopGetCurrent(); 获取当前线程的CFRunLoopRef对象。
  4. CFRunLoopGetMain(); 获取主线程的CFRunLoopRef对象。
  5. NSRunLoop *runLoop = [[NSRunLoop alloc] initWithMode:NSDefaultRunLoopMode]; 创建一个新的RunLoop对象。
    一旦获取了RunLoop对象,就可以向其中添加定时器、端口等输入源,以便监听事件。添加输入源的方法如下:
  6. [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; 将定时器添加到当前线程的RunLoop中。
  7. CFRunLoopAddTimer(CFRunLoopRef runLoop, CFRunLoopTimerRef timer, CFRunLoopMode mode); 将定时器添加到指定线程的RunLoop中。
  8. [[NSRunLoop currentRunLoop] addPort:port forMode:NSDefaultRunLoopMode]; 将端口添加到当前线程的RunLoop中。
  9. CFRunLoopAddSource(CFRunLoopRef runLoop, CFRunLoopSourceRef source, CFRunLoopMode mode); 将源添加到指定线程的RunLoop中。
    启动RunLoop的方法如下:
  10. [[NSRunLoop currentRunLoop] run]; 无条件且以默认的NSDefaultRunLoopMode启动当前线程的RunLoop。
  11. [[NSRunLoop currentRunLoop] runUntilDate:[NSDate date]]; 指定过期时间且以默认的NSDefaultRunLoopMode启动当前线程的RunLoop。
  12. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate date]]; 指定过期时间,指定启动方式启动当前线程的RunLoop。
    需要注意的是,NSRunLoop对象不是线程安全的,如果在不同线程中使用同一个RunLoop对象,可能会导致竞态条件或死锁问题。因此,建议在不同线程中使用独立的RunLoop对象,或者使用CFRunLoopRef来保证线程安全。同时,子线程的RunLoop随着所在子线程的事件源结束而关闭,随着所在子线程的结束而释放。