从完成块中解散视图控制器 - Swift

10

简单的问题。如果我在完成块中 - 例如使用 Firebase 进行 Facebook 登录...并且登录成功了。如果我想要从完成块内部取消当前视图控制器(登录视图控制器),我需要回到主队列来执行此操作吗?我假设登录完成块正在后台线程上进行,对 UI 的任何更改(即取消当前视图控制器)都应该在主线程上完成...这里有什么最佳实践...或者我漏掉了什么吗?

@IBAction func facebookLoginTapped(sender: AnyObject) {

    //
    let ref = Firebase(url: "https://XXXX.firebaseio.com")
    let facebookLogin = FBSDKLoginManager()
    facebookLogin.logInWithReadPermissions(["email"], fromViewController: self, handler: { (facebookResult, facebookError) -> Void in
        if facebookError != nil {
            print("Facebook login failed. Error \(facebookError)")
        } else if facebookResult.isCancelled {
            print("Facebook login was cancelled.")
        } else {
            //successfully logged in
            //get facbook access token
            let accessToken = FBSDKAccessToken.currentAccessToken().tokenString
            //use access token to authenticate with firebase
            ref.authWithOAuthProvider("facebook", token: accessToken,
                withCompletionBlock: { error, authData in
                    if error != nil {
                        print("Login failed. \(error)")
                    } else {
                        //authData contains
                        print("Logged in! \(authData)")

                        //pop loginvc back to uservc - DO I NEED TO GET MAIN THREAD HERE BEFORE DISMISSING VIEW CONTROLLER
                        self.dismissViewControllerAnimated(true, completion: nil)
                    }
            })
        }
    })
}

与我的有关 performSegue 的答案相同:https://dev59.com/BlwY5IYBdhLWcg3wuZym#32292706 - BaseZen
3
你必须在主线程上执行它。 - ryantxr
1个回答

18

您应该“弹回”到主线程来执行此操作。这很简单,只需像这样包装:

DispatchQueue.main.async {
    self.dismissViewControllerAnimated(true, completion: nil)
}

Swift 2.x

dispatch_async(dispatch_get_main_queue()){
    self.dismissViewControllerAnimated(true, completion: nil)
}

Swift 3、4和5:

DispatchQueue.main.async {
      self.dismiss(animated: true, completion: nil)
}

如果从DispatchQueue.global(qos: .background).async调用,则无法工作。 - Yaroslav Dukal
1
你需要在主线程上进行UI更新。不要从后台线程调用此方法。 - MikeG
但我正在使用 DispatchQueue.main.async。 - Yaroslav Dukal
我不明白,请您提出问题并附上代码和链接,我会查看的。 - MikeG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接