V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
main1234
V2EX  ›  Swift

Swift 萌新, DispatchQueue 的一个问题

  •  
  •   main1234 · 19 天前 · 1371 次点击

    使用的 Xcode 16.2 、swift 6.0.3

    代码如下

    import Foundation
    
    DispatchQueue.global().async {
        // 耗时操作(如网络请求、文件处理)
        let data = downloadData()
        
        DispatchQueue.main.async {
            updateUI(with: data)
        }
    }
    
    func downloadData() -> String{
        sleep(2)
        return "a"
    }
    
    func updateUI(with: Any) {
        print("updateUI")
    }
    
    sleep(10)
    
    

    为什么我无法输出 updateUI

    我应该如何在切换到主线程时候,让主线程输出 updateUI

    16 条回复    2025-06-04 00:30:52 +08:00
    kera0a
        1
    kera0a  
       19 天前 via iPhone
    主线程已经提前被 sleep(10)阻塞了,等 sleep 结束后程序估计也终止了
    iOCZS
        2
    iOCZS  
       19 天前
    主线程如何保持运行?
    byby
        3
    byby  
       19 天前 via iPhone
    老方法用闭包 completion ,新方法用 async await
    iyeatse
        4
    iyeatse  
       19 天前   ❤️ 1
    把 `sleep(10)` 改成 `dispatchMain()`
    MacsedProtoss
        5
    MacsedProtoss  
       19 天前
    main:|——————————( sleep 10)——————————|
    dispatchGlobal. print(“updateUI”)
    global: ——(sleep 2)——|
    dispatchMain

    为啥你要在主线程 sleep 阻塞住它呢?
    MacsedProtoss
        6
    MacsedProtoss  
       19 天前
    @MacsedProtoss 奇怪…好像空格都被吃掉了,我的 format 全都失效了….
    chiaf
        7
    chiaf  
       19 天前 via iPhone
    看描述,这好像是全部代码,没有 main 函数怎么运行🤪

    如果是在 playground 里面,肯定能打印出来。
    yoyoyoyolol
        8
    yoyoyoyolol  
       18 天前
    你给的代码由于 sleep(10)卡住主线程了,导致 10 秒后才能打印 updateUI 。
    因为 palyground 没有 runloop 环境,你要想实现 2 秒后打印的效果,可以这样写

    import Foundation
    import PlaygroundSupport // 关键导入

    // 让 Playground 持续运行,不自动结束
    PlaygroundPage.current.needsIndefiniteExecution = true

    DispatchQueue.global().async {
    // 耗时操作(如网络请求、文件处理)
    let data = downloadData()

    DispatchQueue.main.async {
    updateUI(with: data)
    }
    }

    func downloadData() -> String {
    sleep(2)
    return "a"
    }

    func updateUI(with: Any) {
    print("updateUI")
    }

    // 不需要 sleep(10),Playground 会保持运行

    其中 PlaygroundPage.current.needsIndefiniteExecution = true 这一句话可以让 palyground 开启 runloop 环境,避免了主线程使用 sleep 卡住线程
    magic3584
        9
    magic3584  
       18 天前
    看着像是在 Playground 里。
    建议创建一个项目在 viewController 里去调用
    shixiaoda
        10
    shixiaoda  
       18 天前
    看到 iOS developer 后继有人,甚是欣慰
    main1234
        11
    main1234  
    OP
       18 天前
    @shixiaoda 老哥为啥这么说,IOS 开发不用 swift 了嘛
    main1234
        12
    main1234  
    OP
       18 天前
    @iOCZS 对,如何让主线程保持运行呢
    main1234
        13
    main1234  
    OP
       18 天前
    @chiaf 啊? swift 不也支持面向过程么
    main1234
        14
    main1234  
    OP
       18 天前
    @MacsedProtoss 萌新,我想让主线程不退出
    MacsedProtoss
        15
    MacsedProtoss  
       18 天前 via iPhone
    @main1234 主线程不退出是 runloop 机制实现的 如果你用纯 swift cli 去跑那肯定不行
    BeiChuanAlex
        16
    BeiChuanAlex  
       2 天前
    @shixiaoda #10 哈哈哈,笑死了,宗门已经没落成这样了嘛
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2625 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 66ms · UTC 11:57 · PVG 19:57 · LAX 04:57 · JFK 07:57
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.