美文网首页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

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