在我的应用程序中,我有一个函数,使一个nsururlsession和发送一个NSURLRequest使用

sesh.dataTaskWithRequest(req, completionHandler: {(data, response, error)

在这个任务的完成块中,我需要做一些计算,将一个UIImage添加到调用视图控制器中。我有一个func叫

func displayQRCode(receiveAddr, withAmountInBTC:amountBTC)

它做uiimage添加计算。如果我试图在完成块中运行视图添加代码,Xcode抛出一个错误,说我不能在后台进程中使用布局引擎。所以我在So上找到了一些代码,试图在主线程上排队一个方法:

let time = dispatch_time(DISPATCH_TIME_NOW, Int64(0.0 * Double(NSEC_PER_MSEC)))

dispatch_after(time, dispatch_get_main_queue(), {
    let returned = UIApplication.sharedApplication().sendAction("displayQRCode:", to: self.delegate, from: self, forEvent: nil)
})

但是,我不知道如何将参数“receiveAddr”和“amountBTC”添加到这个函数调用。我将如何做到这一点,或者有人可以建议一种向应用程序的主队列添加方法调用的最佳方法吗?


当前回答

对于现代Swift代码(Swift 5.5+和iOS 13+),苹果建议将主线程任务交给main Actor,而不是GCD,以获得更干净、性能更好、更安全的代码。

在这里,我详细介绍了使用actor向主线程调度的4种方法。

最简单的方法是使用@MainActor属性包装器对该方法进行注释。

@MainActor func callFunctionOnMainThread(paramOne: Int, paramTwo: String) {
    // We can now access parameters on the main thread
}

我们使用结构化并发,即async/await:

await callFunctionOnMainThread(paramOne: 2, paramTwo: "Two")

其他回答

如果你在闭包中使用self,不要忘记弱化self。

dispatch_async(dispatch_get_main_queue(),{ [weak self] () -> () in
    if let strongSelf = self {
        self?.doSomething()
    }
})
//Perform some task and update UI immediately.
DispatchQueue.global(qos: .userInitiated).async {  
    // Call your function here
    DispatchQueue.main.async {  
        // Update UI
        self.tableView.reloadData()  
    }
}

//To call or execute function after some time
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
    //Here call your function
}

//If you want to do changes in UI use this
DispatchQueue.main.async(execute: {
    //Update UI
    self.tableView.reloadData()
})

这里有一个不错的小全局函数,你可以添加一个更好的语法:

func dispatch_on_main(block: dispatch_block_t) {
    dispatch_async(dispatch_get_main_queue(), block)
}

和使用

dispatch_on_main {
    // Do some UI stuff
}

对于现代Swift代码(Swift 5.5+和iOS 13+),苹果建议将主线程任务交给main Actor,而不是GCD,以获得更干净、性能更好、更安全的代码。

在这里,我详细介绍了使用actor向主线程调度的4种方法。

最简单的方法是使用@MainActor属性包装器对该方法进行注释。

@MainActor func callFunctionOnMainThread(paramOne: Int, paramTwo: String) {
    // We can now access parameters on the main thread
}

我们使用结构化并发,即async/await:

await callFunctionOnMainThread(paramOne: 2, paramTwo: "Two")

正确的方法是在main_queue中使用dispatch_async,就像我在下面的代码中所做的那样

dispatch_async(dispatch_get_main_queue(), {
    (self.delegate as TBGQRCodeViewController).displayQRCode(receiveAddr, withAmountInBTC:amountBTC)
})