【问题标题】:MACOS App closure never executedMACOS 应用程序关闭从未执行
【发布时间】:2017-04-20 07:54:35
【问题描述】:

我在 swift 中创建了一个 macOS 控制台应用程序,但代码从未执行,=我必须使用 Semaphore 但有其他方法吗? 我的目的是创建一个返回 json 文件的方法

class test{
    func gizlo(){
        let config = URLSessionConfiguration.default // Session Configuration
        let session = URLSession(configuration: config) // Load configuration into Session
        let url = URL(string: "https://itunes.apple.com/fr/rss/topmovies/limit=25/json")!

        let task = session.dataTask(with: url, completionHandler: {
            (data, response, error) in

            if error != nil {

                print(error!.localizedDescription)

            } else {

                do {

                    if let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any]
                    {
                        print(json)
                    }

                } catch {

                    print("error in JSONSerialization")

                }


            }

        })

        task.resume()
    }
}

let tr=test()
tr.gizlo()

谢谢

【问题讨论】:

标签: swift macos macos-sierra


【解决方案1】:

为了避免信号量,您可以使用简单的readLine(),它将等待来自键盘的输入。是的,这并不明显,但它正在唤醒,因为它阻止了终端应用程序退出。

只需添加文件的和:

_ = readLine()

【讨论】:

    【解决方案2】:

    正如 Oleg 指出的那样,将 readLine() 放在顶层代码的末尾将阻止程序退出,直到您在终端中点击 EnterFileHandle.standardInput 指向的任何位置。这对于在调试器或 Playground 中快速测试代码可能很好。无限循环也可以工作,但您必须在调试器中或在命令行中使用 kill 实际终止它。

    真正的问题是为什么您不想使用信号量。由于它们不难使用,我将冒险猜测这只是因为您不想用信号量污染异步数据任务完成处理程序,而您可能只需要它来等待数据进行测试目的。

    假设我的猜测是正确的,真正的问题实际上并不是使用信号量,而是您认为需要放置信号量的地方。正如 David Wheeler 曾经说过的那样,“任何问题都可以通过添加一层间接来解决。”

    您不希望在传递给dataTask 的完成处理程序中显式地使用信号量。因此,一种解决方案是让gizlo 接受它自己的完成处理程序,然后创建一个调用gizlo 的方法,并使用一个处理信号量的闭包。这样,您可以将两者解耦,甚至为其他用途增加一些灵活性。我已经修改了你的代码来做到这一点:

    import Foundation
    import Dispatch // <-- Added - using DispatchSemaphore
    
    class test{
        func gizlo(_ completion: ((Result<[String: Any]?, Error>) -> Void)? = nil) { // <-- Added externally provided completion handler
            let config = URLSessionConfiguration.default // Session Configuration
            let session = URLSession(configuration: config) // Load configuration into Session
            let url = URL(string: "https://itunes.apple.com/fr/rss/topmovies/limit=25/json")!
    
            let task = session.dataTask(with: url, completionHandler: {
                (data, response, error) in
    
                let result: Result<[String: Any]?, Error>
                if let responseError = error { // <-- Changed to optional binding
    
                    print(responseError.localizedDescription)
                    result = .failure(responseError) // <-- Added this
    
                } else {
    
                    do {
    
                        if let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any]
                        {
                            print(json)
                            result = .success(json) // <-- Added this
                        }
                        else { // <-- Added this else block
                            result = .success(nil)
                        }
                    } catch {
    
                        print("error in JSONSerialization")
                        result = .failure(error) // <-- Added this
                    }
    
                }
    
                completion?(result)  // <-- Added this call
            })
    
            task.resume()
        }
    
        func blockingGizlo() throws -> [String: Any]? // <-- Added this method
        {
            let sem = DispatchSemaphore(value: 1)
            sem.wait()
            var result: Result<[String: Any]?, Error>? = nil
            gizlo {
                result = $0
                sem.signal()
            }
            sem.wait() // This wait will block until the closure calls signal
            sem.signal() // Release the second wait.
    
            switch result
            {
                case .success(let json)  : return json
                case .failure(let error) : throw error
                case .none: fatalError("Unreachable")
            }
        }
    }
    
    let tr=test()
    
    do {
        let json = try tr.blockingGizlo()
        print("\(json?.description ?? "nil")")
    }
    catch { print("Error: \(error.localizedDescription)") }
    

    【讨论】:

      猜你喜欢
      • 2017-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-25
      • 1970-01-01
      • 1970-01-01
      • 2013-12-14
      • 2016-08-28
      相关资源
      最近更新 更多