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

piztneat  于 2023-02-10  发布在  iOS
关注(0)|答案(4)|浏览(158)

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

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

现在,我希望该方法仅在为变量而不是空字符串设置了xyz值之后才返回。
如何做到这一点?

zphenhs4

zphenhs41#

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

您必须使用一些可以阻塞线程直到资源可用的东西,比如信号量

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

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

    semaphore.wait()
    return string
}

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

ccrfmcuu

ccrfmcuu2#

是的,可以等待闭包函数填充数据,然后返回变量。虽然,建议避免使用信号量来做这件事,但我认为这是唯一的方法。

func foo() -> String {
    var str = ""
    let semaphore = DispathSemaphore(value: 1)  //1 if you are waiting for one closure function to signal the semaphore to continue the main thread execution

    getAsync() {
        //populate the variable
        str = "bar"
        semaphore.signal()
    }
    semaphore.wait()
    return str
}
odopli94

odopli943#

从Swift 5.5开始,推荐使用async/await。如果API没有提供async版本,您可以使用Continuation创建自己的版本

func testMethod() async -> String {
    return await withCheckedContinuation({ continuation in
        someAsynchronousServiceCallBlock() { result in
            continuation.resume(returning: result)
        }
    })
}

您必须在异步上下文中调用该方法,例如在Task

Task {
    let result = await testMethod()
}
f1tvaqid

f1tvaqid4#

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

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")
    }
}

相关问题