RunLoop

334 阅读2分钟

大神链接

  • RunLoop

RunLoop 实际上是一个对象,这个对象在循环中处理程序运行中出现的各种事件(触摸事件,UI刷新事件,定时器事件,Selector事件),从而保持程序持续运行.没有事件处理对象会进入睡眠模式,从而节省CPU资源提高程序性能.

  • RunLoop 与线程
1. 一条线程对应一个RunLoop,每一条线程都有唯一一个与之对应的RunLoop对象;
2. 只能在当前线程操作当前线程的RunLoop,不能去操作其他线程的RunLoop;
3. RunLoop对象在线程开始时创建,在线程结束时销毁.
  • RunLoop 类
 CFRunLoopRef RunLoop对象
 CFRunLoopModeRef RunLoop运行模式
 CFRunLoopSourceRef 输入源
 CFRunLoopTimerRef 定时源
 CFRunLoopObserverRef 观察者,监听RunLoop状态

一个RunLoop对象(CFRunLoopRef)中包含若干个运行模式(CFRunLoopModeRef).而每一个运行模式(CFRunLoopModeRef)又包含若干个输入源(CFRunLoopSourceRef),定时源(CFRunLoopTimerRef),观察者(CFRunLoopObserverRef).

每次启动一个RunLoop时,只能指定其中一种运行模式(CFRunLoopModeRef),称为CurrentMode.如果需要切换运行模式,只能推出Loop,再重新指定一个运行模式进入,这样做是为了分开不同组的输入源,定时源,观察者,让其互不影响.

  • CFRunLoopModeRef 运行模式
1. kCFRunLoopDefaultMode App默认运行模式,通常主线程是在这个运行模式下运行的
2. UITrackingRunLoopMode 跟踪交互事件
3. UIInitializationRunLoopMode App启动时进入的第一个模式,启动完成后便不再使用
4. GSEventReceiveRunLoopMode 接受系统内部事件,通常用不到
5. kCFRunLoopCommonModes 伪模式,不是一种真正的运行模式
  • 例子
override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .white
        
        let scrollView = UIScrollView(frame: CGRect(x: 50.0, y: 100.0, width: 100.0, height: 100.0))
        scrollView.backgroundColor = .orange
        scrollView.contentSize = CGSize(width: 100.0, height: 200.0)
        self.view.addSubview(scrollView)

        timer = Timer(timeInterval: 2.0, target: self, selector: #selector(runLoopAction), userInfo: nil, repeats: true)
        RunLoop.current.add(timer!, forMode: .default)
        
    }
    
    deinit {
        timer?.invalidate()
    }
    
    @objc func runLoopAction() {
        NSLog("=== run ===")
    }
使用 kCFRunLoopDefaultMode 模式时,滑动 UIScrollView 不打印.
使用 UITrackingRunLoopMode 模式时,只有滑动 UIScrollView 才会打印. 
使用 kCFRunLoopCommonModes 模式时,不管滑不滑动 UIScrollView 都会打印