在DispatchQueue.main.async Swift 3中转义闭包设置视图

时间:2017-08-04 00:47:17

标签: asynchronous swift3 callback closures dispatch

我正在处理一些异步函数并尝试更新视图。简而言之,我有一个带异步函数的函数1,它将返回一个传递给函数2的字符串。我在两个函数中更新视图,在主线程上。这一切都有效,但我需要了解这是否正确。

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)在另一个异步回调中调用异步func是否可以?如果你在某些逃避函数中更新视图,那么在某些情况下self是否可能为零?

1 个答案:

答案 0 :(得分:2)

我会根据你的问题尝试帮助你:

问题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 - 我在这里使用[弱自我]到avoid retain cycles

2 - 只需打开可选的自我,案件没有,我就会回来。

3 - 在你的情况下,没有必要拥有类变量,所以我只是在块中创建局部变量。

4 - 最后,我用包含字符串的变量调用完成。

5 - 我也不需要在这里设置一个类变量,因此我只是使用作为参数提供的字符串更新标签文本。

6 - 然后,我只需要调用第一个函数并使用完成块在第一个函数完成后调用第二个函数。

问题2)是的,您必须致电DispatchQueue.main来更新视图。这样你就可以确保你的代码将在主线程中执行,这对于与UI交互的东西至关重要,因为它允许我们在Apple's documentation中读取一个sincronization点。

问题3)使用[weak self]guard let strongSelf = self else { return },我避免了保留周期以及self可以nil的情况。