SwiftUI, как запустить веселье c после того, как другой полностью завершен - PullRequest
0 голосов
/ 23 февраля 2020

Я запускаю забавный c, который входит в для l oop и добавляет к массиву. В следующей строке я запускаю другую забаву c, которая использует первый элемент этого массива, однако приложение вылетает, поскольку во время 2-го исполнения забавы c оно находит массив пустым. Я использовал syn c () очереди и обработчики завершения, но проблема все еще есть. Единственный способ, которым он работает в данный момент, - это вызвать таймер, чтобы подождать несколько секунд, но это, конечно, не идеальный способ сделать это. Есть ли у вас какие-либо предложения? 1-е веселье c выглядит следующим образом:

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 голосов
/ 25 февраля 2020

Трудно увидеть, что ты пытаешься сделать. Проверьте следующий фрагмент Playground, который использует NSOpenPanel для выбора некоторых файлов .swift и асинхронно (случайная задержка имитирует использование в реальном мире) вычисляет длину его абсолютного пути и показывает результаты в 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

...