SwiftUI如何在另一个完全完成后运行func

时间:2020-02-23 18:00:58

标签: swift xcode macos swift5 appkit

我正在运行一个函数,该函数进入for循环并追加到数组中。在下一行中,我正在运行另一个使用该数组的第一个元素的函数,但是,该应用程序崩溃,因为在执行第二个函数时,它发现该数组为空。我使用过sync()队列和完成处理程序,但确实有问题。目前,它唯一起作用的方法是调用Timer等待几秒钟,但这当然不是理想的方法。你有什么建议吗? 第一个功能如下:

func openRun () {
                        let openPanel = NSOpenPanel()
                        ...
                            if result.rawValue == NSApplication.ModalResponse.OK.rawValue {
                                let rawURL = openPanel.url!.path
                                //some codes that extract image files from the openned path
                                    for image in imageList {
                                        images.append(newImage)   
                                    }

                            }
                        }

1 个答案:

答案 0 :(得分:0)

很难理解,您尝试做什么。检查下一个使用NSOpenPanel选择.swift文件并异步(随机延迟模拟现实情况的使用)的Playground片段,计算其绝对路径的长度并在SwiftUI View中显示结果。

//: A Cocoa based Playground to present user interface

import AppKit
import SwiftUI
import PlaygroundSupport

let panel = NSOpenPanel()
panel.allowsMultipleSelection = true
panel.allowedFileTypes = ["swift"]

struct Info: Identifiable {
    let id = UUID()
    let txt: String
    let length: Int
}

struct ContentView: View {
    @State var arr: [Info] = []
    var body: some View {
        VStack {
            Button(action: {
                panel.begin { (respond) in
                    panel.urls.forEach { (url) in
                        self.urlLength(url: url) { (i) in
                            self.arr.append(Info(txt: url.lastPathComponent, length: i))
                        }
                    }
                }
            }) {
                Text("action")
            }.padding()

            List(arr) { (item) in
                HStack {
                    Text(item.txt)
                    Text(item.length.description).foregroundColor(Color.yellow)
                }
            }
        }.frame(width: 200, height: 400)
            .border(Color.red)
    }

    func urlLength(url: URL, completion: @escaping (Int)->()) {
        DispatchQueue.global().asyncAfter(deadline: .now() + Double.random(in: 0.0 ..< 3.0)) { [url] in
            let c = url.absoluteString.count
            DispatchQueue.main.async {
                completion(c)
            }
        }
    }
}

PlaygroundPage.current.setLiveView(ContentView())

这个有趣的示例演示了如何在SwiftUI中使用异步代码

enter image description here