如何在返回值之前等待闭包完成

Ars*_*akh 5 closures asynchronous ios swift

如何在关闭完成后等待返回值.

例:

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

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

怎么做到这一点?

Jak*_*lář 6

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

您必须使用诸如信号量之类的会阻塞线程直到资源可用的方法。

var foo: String {
    let semaphore = DispatchSemaphore(value: 0)
    var string = ""

    getSomethingAsynchronously { something in
        string = something
        semaphore.signal()
    }

    semaphore.wait()
    return string
}
Run Code Online (Sandbox Code Playgroud)

切记,正在处理的线程将被阻塞,直到getSomethingAsynchronously完成。

  • @vadian您有“几乎所有”的数字吗?这是一个很合法的问题,实际上我是由于`XCTestObservation`函数`testBundleDidFinish`的特定要求而找到该线程的,它需要阻塞线程直到完成。我同意在这里容易出错,但是不要以为没有人会需要它;) (2认同)
  • 使用 Grand Central Dispatch 等待异步回调被认为是一种性能反模式,因为它会创建无用的线程并且会受到优先级反转的影响。从 Xcode 10 开始,静态分析器会将此作为潜在的“问题”突出显示(单元测试中除外)。 (2认同)

Kon*_*ann -5

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

你可以做的是这样的:

func testmethod(callback: (abc: String) -> Void) {
   asyncTask() {
     callback(abc: "xyz")
   }
}
Run Code Online (Sandbox Code Playgroud)

祝你今天过得愉快。

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

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