gpt4 book ai didi

swift - 运行异步调用时在 MainQueue 上更新什么

转载 作者:可可西里 更新时间:2023-11-01 02:04:41 27 4
gpt4 key购买 nike

我向 Firebase 发送了一些信息,如果成功,回调中可能会发生 5 件事,如果不成功,可能会发生 3 件事:

如果成功:

  1. 事件指示器已关闭

  2. 具有日期更新的类级别变量

  3. 出现一个警告,其中包含一条包含该变量的消息

  4. 推送到另一个vc

  5. sendButton 再次启用(一旦他们按下它就被禁用)

如果不成功:

  1. 事件指示器已关闭

  2. 出现一条警告消息,表明它不成功

  3. sendButton 再次启用(一旦他们按下它就被禁用)

当我尝试将 navigationController?.pushViewController 放在 mainQueue 上时,它总是有问题,特别是它并不总是执行。

//caused problems
DispatchQueue.main.async {
navigationController?.pushViewController(nextVC, animated: false)
}

一旦我将其取下并将其留在后台,它就可以正常运行。我知道我应该更新警报,但是警报使用的类级别变量和关闭事件指示器呢?

Firebase 代码:

@IBOutlet weak fileprivate var sendButton: UIButton!

let date = Date() //formatted in viewDidLoad
var todaysDate = ""
let activityIndicator = UIActivityIndicatorView() //formatted in viewDidLoad

@IBAction fileprivate func sendButtonTapped(_ sender: UIButton){

sendButton.isEnabled = false
view.addSubview(activityIndicator)

//dict has some values

nextVCRef?.updateChildValues(dict, withCompletionBlock: {
(error, ref) in

if error != nil{

DispatchQueue.main.async {
self.activityIndicator.removeFromSuperView
self.alertError()
self.sendButton.isEnabled = true//i normally would put this is the alertError action but for clarity i put it here
}
return
}

DispatchQueue.main.async {
self.todaysDate = self.date
self.alertSuccessful()//everything happens in the function
}
})
}

fileprivate alertSuccessful(){
self.activityIndicator!.removeFromSuperView
let alert = UIAlertController(title: "Thank You!", message: "Today's date is \(self.todaysDate).", preferredStyle: UIAlertControllerStyle.alert)
let action = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default){
(action) in
self.sendButton.isEnabled = true
_ = self.navigationController?.pushViewController(nextVC, animated: false)
}
alert.addAction(action)
present(alert, animated: true, completion: nil)
}

fileprivate alertError(){
let alert = UIAlertController(title: "Unknown Error!", message: "There was an error. Try again.", preferredStyle: UIAlertControllerStyle.alert)
let action = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil)
alert.addAction(action)
present(alert, animated: true, completion: nil)
}
}

问题是在设置变量、关闭事件指示器、出现警报、重新启用 sendButton 和执行推送之间,应该不应该 在主队列中?

顺便说一句,我不需要在后台更新日期变量,但在另一种情况下,我可能会从 Firebase 中提取一些信息,并且该变量将在回调中更新。我没有包含该代码而是使用了它,因为要点是类变量是否应该在后台线程的主队列上更新?

最佳答案

正如@shallowThought 在答案下方的评论中指出的那样,任何具有 UI 前缀的内容,如 UINavigationControllerUIViewUIActivityIndi​​catorUIButton 都是 user interface 对象,应该在 mainQueue 上。 mainQueue 专门用于用户界面对象或缩写UI 对象。多亏了他,一些东西很容易记住 :) 变量也应该更新。

@Paulo Mattos 在评论中指出,我不知道 Firebase 的美妙之处在于,Firebase 完成 block 全部发生在 mainQueue 上,因此它减轻了必须添加 DispatchQueue.main.asyc 的麻烦{} p>

为他们的评论点赞!

关于swift - 运行异步调用时在 MainQueue 上更新什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44165601/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com