iOS异步功能不正常

时间:2019-01-25 11:25:34

标签: ios swift asynchronous

我是异步方面的新手,我正在尝试实现对函数的简单异步调用。

import UIKit

func doAsyncStuff ( completionHandler: (_ result: Double) -> Void) {
    print("start async")
    sleep(5)   // to simulate long work
    let result: Double = 123.456
    completionHandler(result)
}

print("A")

doAsyncStuff() { result in
    print(result)
}

print("B")

执行时,我得到

A
start async
123.456
B

由于func是异步调用的,所以我希望得到

A
start async
B
123.456

我哪里出错了? 非常感谢

4 个答案:

答案 0 :(得分:3)

问题在于您正在调用sleep,这是一个同步阻塞函数,因此您将主线程阻塞了5秒钟,并且在此期间无法执行其他任何操作。您应该使用DispatchQueue.asyncAfter测试简单的异步调用。

您还可以知道您的函数不是异步的,因为没有收到未将闭包标记为@escaping的编译器错误,您需要对异步完成处理程序执行此操作。

func doAsyncStuff(completionHandler: @escaping (_ result: Double) -> Void) {
    print("start async")
    DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
        completionHandler(123.456)
    }
}

答案 1 :(得分:2)

您的函数不是异步的。每行代码都正在同步运行(即在执行之前等待该行完成)。因此sleep(5)在函数中间暂停执行,直到函数返回后才调用print(“ B”)。

您可以使用Grand Central Dispatch (GCD)在不同线程上异步运行代码。这是一个示例:

import UIKit

func doAsyncStuff ( completionHandler: (_ result: Double) -> Void) {
    DispatchQueue.global(qos: .background).async { [weak self] in
        print("start async")
        sleep(5)
        let result: Double = 123.456
        completionHandler(result)
    }
}

print("A")

doAsyncStuff() { result in
    print(result) // This is your completion handler code
}

print("B")

答案 2 :(得分:1)

当心,您正在同一线程上调用函数,因此它将是同步的!

要以异步方式调用它,请创建一个后台线程/任务,然后从该后台线程调用您的函数。一种方法:

print("A")
DispatchQueue.global(qos: .background).async {
    //this is a background thread, do in it your async stuff
    doAsyncStuff() { result in
        print(result)
    }
}
print("B")

答案 3 :(得分:1)

使用 DispatchQueue.main.asyncAfter 快速进行异步调用。 因此您的代码应该看起来像..

func doAsyncStuff ( completionHandler: (_ result: Double) -> Void) {
    print("start async")
    DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
    // your code goes from here
        let result: Double = 123.456
        completionHandler(result)
    }

}