Asynchronous 在DispatchQueue.main.async Swift 3中转义闭包设置视图
我正在处理一些异步函数并尝试更新视图。简而言之,我有一个带有异步函数的函数1,该函数将返回一个字符串以传递给函数2。我正在主线程上更新这两个函数中的视图。这一切都是可行的,但我需要了解这是否是正确的方式Asynchronous 在DispatchQueue.main.async Swift 3中转义闭包设置视图,asynchronous,swift3,callback,closures,dispatch,Asynchronous,Swift3,Callback,Closures,Dispatch,我正在处理一些异步函数并尝试更新视图。简而言之,我有一个带有异步函数的函数1,该函数将返回一个字符串以传递给函数2。我正在主线程上更新这两个函数中的视图。这一切都是可行的,但我需要了解这是否是正确的方式 class A { var varA = "" var varB = "" func f1 (_ completion: @escaping (String) -> void ){ some asynchronous call ... { in
class A {
var varA = ""
var varB = ""
func f1 (_ completion: @escaping (String) -> void ){
some asynchronous call ... { in
...
DispatchQueue.main.async {
self.varA = "something"
sef.labelA.text = self.varA
completion(self.varA)
}
}
}
func f2 (_ string: String){
another asynchronous call ... { in
...
DispatchQueue.main.async {
self.varB = string
sef.labelB.text = self.varB
}
}
}
// funcation call
f1(completion: f2)
}
有三个问题,1)在存在等待异步回调的情况下,运行依赖函数的正确方法是什么
2) 更新视图是否需要DispatchQueue.main.async
3) 在另一个异步回调中调用async func可以吗?如果您在某些转义函数中更新视图,在某些情况下self不可能为零吗?我将根据您的问题尝试帮助您: 问题1)有很多正确的方法,每个开发人员都可以有自己的逻辑,但在这种情况下,我个人可能会这样做:
class A {
func f1 (_ completion: @escaping (String) -> void ){
some asynchronous call ... { in
...
DispatchQueue.main.async { [weak self] in // 1
guard let strongSelf = self else { return } // 2
let varA = "something" // 3
strongSelf.label.text = varA
completion(varA) // 4
}
}
}
func f2 (_ string: String){
another asynchronous call ... { in
...
DispatchQueue.main.async {
sef.labelB.text = string // 5
}
}
}
// function call
// 6
f1(completion: { [weak self] text in
guard let strongSelf = self else { return }
strongSelf.f2(text)
})
}
1-在这里,我使用[弱自我]来解决问题
2-只要打开可选的自我包装,如果它为零,我就返回
3-在您的例子中,实际上不需要类变量,所以我只是在块内创建局部变量
4-最后,我用包含字符串的变量调用completion
5-我也不需要在这里设置类变量,所以我只是用作为参数提供的字符串更新标签文本
6-然后,我只需要调用第一个函数,并在第一个函数完成后使用完成块调用第二个函数
问题2)是的,您必须调用DispatchQueue.main
来更新视图。通过这种方式,您可以确保您的代码将在主线程中执行,这对于与UI交互的事情至关重要,因为它允许我们有一个您可以读入的sincronization点
问题3)使用
[弱自我]
和guard let strongSelf=self-else{return}
,我将避免保留周期和self
可能为nil
的情况,我将根据您的问题尝试帮助您:
问题1)有很多正确的方法,每个开发人员都可以有自己的逻辑,但在这种情况下,我个人可能会这样做:
class A {
func f1 (_ completion: @escaping (String) -> void ){
some asynchronous call ... { in
...
DispatchQueue.main.async { [weak self] in // 1
guard let strongSelf = self else { return } // 2
let varA = "something" // 3
strongSelf.label.text = varA
completion(varA) // 4
}
}
}
func f2 (_ string: String){
another asynchronous call ... { in
...
DispatchQueue.main.async {
sef.labelB.text = string // 5
}
}
}
// function call
// 6
f1(completion: { [weak self] text in
guard let strongSelf = self else { return }
strongSelf.f2(text)
})
}
1-在这里,我使用[弱自我]来解决问题
2-只要打开可选的自我包装,如果它为零,我就返回
3-在您的例子中,实际上不需要类变量,所以我只是在块内创建局部变量
4-最后,我用包含字符串的变量调用completion
5-我也不需要在这里设置类变量,所以我只是用作为参数提供的字符串更新标签文本
6-然后,我只需要调用第一个函数,并在第一个函数完成后使用完成块调用第二个函数
问题2)是的,您必须调用DispatchQueue.main
来更新视图。通过这种方式,您可以确保您的代码将在主线程中执行,这对于与UI交互的事情至关重要,因为它允许我们有一个您可以读入的sincronization点
问题3)使用
[弱自我]
和guard-let-strongSelf=self-else{return}
,我避免了保留周期和self
可能为nil
的情况,这解释了一些问题。如果我只取出completion:func f1的一部分,然后分别运行f2(varA),会怎么样。如何确保设置varA后f2(varA)运行?由于异步函数有延迟返回,所以用self.f2(varA)替换completion(varA)是否可以,就像在某个asyn闭包中调用函数一样?用self.f2(varA)替换completion(varA)
完全可以,因此您也要确保f2
在f1
完成后运行。通过使用DispatchGroup
,还有另一种方法可以实现这一点,希望这个答案能在您决定这样做时帮助您:在f1的完成方法中,有一个f2调用,它也有一个完成,其中视图实际上正在主线程DispatchQueue.main.async上更新。这是否意味着在f1完成时,我们将在DispatchQueue.main.async{self.f2(varA)}中进行函数调用,或者不需要在主线程上进行调用?这就解释了一些问题。如果我只取出completion:func f1的一部分,然后分别运行f2(varA),会怎么样。如何确保设置varA后f2(varA)运行?由于异步函数有延迟返回,所以用self.f2(varA)替换completion(varA)是否可以,就像在某个asyn闭包中调用函数一样?用self.f2(varA)替换completion(varA)
完全可以,因此您也要确保f2
在f1
完成后运行。通过使用DispatchGroup
,还有另一种方法可以实现这一点,希望这个答案能在您决定这样做时帮助您:在f1的完成方法中,有一个f2调用,它也有一个完成,其中视图实际上正在主线程DispatchQueue.main.async上更新。这是否意味着在f1完成时,我们将在DispatchQueue.main.async{self.f2(varA)}中进行函数调用,或者不需要在主线程上调用该函数?