【问题标题】:How to wait for a closure completion before returning a value如何在返回值之前等待关闭完成
【发布时间】:2015-09-22 04:33:54
【问题描述】:

如何在闭包完成后等待返回值。

例子:

func testmethod() -> String {
   var abc = ""
   /* some asynchronous service call block that sets abc to some other value */ {
      abc = "xyz"
   }
   return abc 
}

现在我希望该方法仅在为变量设置xyz 值而不是空字符串后返回。

如何做到这一点?

【问题讨论】:

    标签: ios swift asynchronous closures


    【解决方案1】:

    有可能 (但请确保这是您真正想要的。)

    您必须使用会阻塞线程直到资源可用的东西,例如信号量

    var foo: String {
        let semaphore = DispatchSemaphore(value: 0)
        var string = ""
    
        getSomethingAsynchronously { something in
            string = something
            semaphore.signal()
        }
    
        semaphore.wait()
        return string
    }
    

    请记住,在getSomethingAsynchronously 完成之前,您正在处理的线程将被阻塞。

    【讨论】:

    • @vadian 当然你应该知道你在做什么以及为什么要这样做,但我不同意这是一个糟糕的建议。由于 OP 想在没有更具体的条件的情况下知道“如何”,并且接受的答案是说这是不可能的,所以这是完全合法的。
    • 几乎所有想等待的人都不知道如何处理异步数据处理。 ?
    • @vadian 你有Almost all 的号码吗?这是一个非常合理的问题,我实际上是因为XCTestObservation 函数testBundleDidFinish 的特定要求而找到了这个线程,它需要阻塞线程直到你完成。我同意这里很容易出错,但不要假设没有人需要这个;)
    • 等待 Grand Central Dispatch 的异步回调被认为是一种性能反模式,因为它会创建无用的线程并且会发生优先级反转。从 Xcode 10 开始,静态分析器会将其突出显示为潜在的“问题”(单元测试中除外)。
    【解决方案2】:

    这是绝对不可能的,因为这不是异步任务的工作方式。

    你可以做的是这样的:

    func testmethod(callback: (abc: String) -> Void) {
       asyncTask() {
         callback(abc: "xyz")
       }
    }
    

    祝你有美好的一天。

    编辑(适用于较新的 Swift 版本):

    func testMethod(callback: @escaping (_ parameter: String) -> Void) {
        DispatchQueue.global().async { // representative for any async task
            callback("Test")
        }
    }
    

    【讨论】:

    • 嗯,有可能。
    猜你喜欢
    • 2020-04-17
    • 2020-09-14
    • 2016-05-08
    • 2021-06-20
    • 1970-01-01
    • 2019-03-03
    • 2021-12-02
    • 1970-01-01
    • 2021-11-07
    相关资源
    最近更新 更多