Swift学习笔记33-多线程与UI渲染

渲染UI的时候必须回到主线程

通过**print(Thread.isMainThread) 来得知是否现在主线程(这是基于foundation的)**

Thread.iscurrent也可以知道是在哪个线程。主线程的线程序号是1,名字是main,子线程是随机生成的,没有名字。

用这个方法来新建线程,具体是哪条是系统随机分配的

swift 复制代码
DispatchQueue.global().async { 
       //一些代码
       }

一个函数的执行顺序是先把自己的内容执行完,然后按随机顺序执行其他线程的内容。

需要用到这个model里的内容去刷新UI界面(比如设置UI界面的文本或者图片),所以在参数里用一个逃逸闭包,把model传出去。

注意这里的model最后是要用来渲染UI的,所以必须在用回调传出model的时候回到主线程

swift 复制代码
func getDetailRequest(block: @escaping ResponseBlock) {
        let dic = ["sys_lan": "1", "result_str": "INFJ"]
        //把dic转成JSON再在URLRequest函数里使用
        
        let jsonStr = dicValuesString(dic as [String : Any])
        print(jsonStr)//这里也有啊
        postRequest(jsonStr: jsonStr, url: RequestSimpleReport.simpleBaseUrl) {
            [weak self] dic in
//            print (dic)
            if let arr = dic as? [Dictionary<String, Any>] {
                if arr.count == 0 {
                    self?.responseBlock?(nil)
                    return
                } else {
                    let model = SimpleReportModel.base(with: arr[0])
                    DispatchQueue.main.async {
                        block(model)
                    }
//                    print(model)
                }
            }
        } 
    }

用SwiftUI写一个组件,然后在ViewController里设置它的大小和位置。

需要用什么就把什么传进来。需要用到model,把model传进来。

swift 复制代码
import SwiftUI
struct ReportView: View {
    var model: SimpleReportModel
    var body: some View {
        Image(systemName: "camera").frame(width: 50, height: 50)
        Text(model.result_str).font(.system(size: 16)).foregroundColor(.blue)
    }
}

然后要用UIKit做底层,也就是在UIViewController里把SwiftUI写好的View导入进去,然后设置

swift 复制代码
lazy var reportView: UIHostingController<ReportView> = {
        let reportView = UIHostingController(rootView: ReportView(model: SimpleReportModel.empty()))
        reportView.view.frame = .init(origin: .zero, size: self.view.frame.size)
        return reportView
    }()

lazy var reportView: UIHostingController<ReportView>用于桥接SwiftUI和UIKit

初始化reportView,UIHostingController是通过获取根视图来初始化的,现在model里还没东西就随便传一个进去(这个model是没有值的所以必须传值)。

然后在需要显示的ViewController调用网络请求函数时,把从网络上请求到的model传给reportView的rootView,就可以使用model渲染页面了。

就像这样:

相关推荐
通信小呆呆1 天前
当算法有了“五感”:多模态数据融合如何向人体感官协同学习?
人工智能·学习·算法·机器学习·机器人
H__Rick1 天前
自动对焦学习-3
人工智能·学习·计算机视觉
Daisy Lee1 天前
量化学习-第1章-什么是量化金融
学习·金融·datawhale
Alsn861 天前
等待学习-学习目录:Docker 容器安全攻防
学习·安全·docker
YM52e1 天前
买菜计算器小应用 - HarmonyOS ArkUI 开发实战-PC版本
学习·华为·harmonyos·鸿蒙·鸿蒙系统
小雨下雨的雨2 天前
HarmonyOS ArkUI训练营入门-组件掌握系列-Animation 动画效果实现-PC版本
学习·华为·harmonyos·鸿蒙
闪闪发亮的小星星2 天前
高斯光以及高斯光公式解释
笔记
cqbzcsq2 天前
CellFlow虚拟细胞论文阅读
论文阅读·人工智能·笔记·学习·生物信息
YangYang9YangYan2 天前
2026初入职场学习数据分析的价值
学习·数据挖掘·数据分析
阿米亚波2 天前
【Windows】QEMU 启动 openEuler aarch64/arm64 架构系统 + 离线软件源
linux·windows·经验分享·笔记·架构·arm