美文网首页iOS开发
iOS为什么在主线程刷新UI

iOS为什么在主线程刷新UI

作者: 7_c5dc | 来源:发表于2018-12-15 20:31 被阅读284次
class UpdateUIViewController: PurpleNavigationViewController {

    var button: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        print("主线程:%@", Thread.main)
        button = UIButton(type: .custom)
        button.setTitle("UI", for: .normal);
        button.titleLabel?.numberOfLines = 0
        button.setTitleColor(UIColor.orange, for: .normal)
        button.backgroundColor = UIColor.lightGray
        button.frame = CGRect(x: 0, y: 70, width: UIScreen.main.bounds.size.width, height: 100)
        button.addTarget(self, action: #selector(buttonDidClick(_:)), for: .touchUpInside)
        view.addSubview(button)
    }

    @objc func buttonDidClick(_ sender: UIButton) {
        //切换到子线程操作UI
        Thread.detachNewThreadSelector(#selector(subThreadTest), toTarget: self, with: nil)
    }
    
    @objc func subThreadTest() {
        
        //step1
        //这里并不会立即更新,而是等休眠4s之后回调主线程再更新
        button.setTitle("当前线程:\(Thread.current)", for: .normal)
        
        //如果想立即更新,需要手动切换到主队列
//        DispatchQueue.main.async {
//            self.button.setTitle("当前线程:\(Thread.current)", for: .normal)
//        }
    
        //step2
        print("当前线程:%@", Thread.current)
        print("主线程:%@,是否是主线程:%d", Thread.main, Thread.isMainThread)
        
        //step3
        let button1 = UIButton(type: .custom)
        button1.setTitle("主线程:\(Thread.main)", for: .normal)
        button1.backgroundColor = UIColor.lightGray
        button1.titleLabel?.numberOfLines = 0
        button1.setTitleColor(UIColor.orange, for: .normal)
        button1.frame = CGRect(x: 0, y: 200, width: UIScreen.main.bounds.size.width, height: 100)
        view.addSubview(button1)
        Thread.sleep(forTimeInterval: 4)
    }
}
结果分析:

从图中点击按钮后,虽然任务是在同一个子线程执行,但是没有按顺序执行

  • step1:更新title没有立即执行
  • step2:打印先于step1执行
  • step3:也没有立即执行
  • 如果想立即更新UI,需要手动切换到主队列,否则要等子线程结束返回到主线程才能刷新UI
结论:
在子线程中是不能进行UI更新的,而可以更新的结果只是一个幻像:因为子线程代码执行完毕了,
又自动进入到了主线程,执行了子线程中的UI更新的函数栈,这中间的时间非常的短,就让大家误以为分线程可以更新UI。
如果子线程一直在运行,则子线程中的UI更新的函数栈主线程无法获知,即无法更新

相关文章

  • iOS中为什么刷新UI要在主线程

    刷新UI要在主线程(简单记个笔记,加深自我理解) 在iOS中,为什么刷新UI要在主线程呢,因为UIKit框架本身就...

  • iOS知识问答

    iOS为什么只能在主线程刷新UI ? 在NSObject中定义run实例方法,之后调用[NSObject perf...

  • 全面详细的GCD用法讲解

    线程概念 iOS程序中,主线程(又叫作UI线程)主要任务是处理UI事件,显示和刷新UI,(只有主线程有直接修改UI...

  • 多线程

    主线程(UI线程) 主线程的主要作用显示和刷新UI界面处理UI事件(比如点击事件、滚动事件、拖拽事件等) iOS中...

  • IOS为什么在主线程刷新UI?(子线程刷新UI测试)

    为什么一定要在主线程刷新UI?安全+效率:因为UIKit框架不是线程安全的框架,当在多个线程进行UI操作,有可能出...

  • 多线程在iOS开发中的应用

    主线程 一个iOS程序运行后,默认会开启一条线程,称为主线程或UI线程 主线程的主要作用显示、刷新UI界面处理UI...

  • iOS拾遗——为什么必须在主线程操作UI

    iOS拾遗——为什么必须在主线程操作UI iOS拾遗——为什么必须在主线程操作UI

  • iOS 多线程开发

    一、概述 在iOS中每个进程启动后都会建立一个主线程(UI线程),这个线程是其他线程的父线程。由于在iOS中除了主...

  • iOS 线程与队列之间的关系

    引导问题:UI刷新,为什么需要在主线程中执行? 原因一:UIKit的操作不是线程安全的 在多个线程下进行UI操作,...

  • iOS之多线程(Multiple threads)小结1.0

    在iOS操作系统中,每一个进程都会有且只有一个主线程,也把这个线程叫做UI线程。UI的刷新都是在主线程中进行的。同...

网友评论

    本文标题:iOS为什么在主线程刷新UI

    本文链接:https://www.haomeiwen.com/subject/gcxzhqtx.html