【问题标题】:Why does my function not execute while using a DispatchQueue?为什么我的函数在使用 DispatchQueue 时不执行?
【发布时间】:2020-07-31 20:29:08
【问题描述】:

有人可以向我解释为什么新视图会在 getMsg() 完成执行之前进入吗?我尝试了许多不同的迭代,但似乎无法弄清楚为什么它不起作用。 onAppear() 有问题吗?还是我使用 DispatchQueue 的方式?

struct ChatView : View {
    @State var msgs = [Msg]()
    @EnvironmentObject var msg : msgDatas
    let group = DispatchGroup()
       var body : some View{
           
           ZStack{
               Color("bg").edgesIgnoringSafeArea(.top)
               
               VStack(spacing: 0){
                   
                   chatTopview()
                   GeometryReader{_ in
                       
                    chatList(msgs: self.msg.msgs).onAppear(){
                        self.group.enter()
                        DispatchQueue.main.async {
                            
                            self.getMsgs()
                            self.group.leave()
                        }
                    }
                    }
                   }
                   
                   chatBottomView()
                   
           }
           .navigationBarTitle("")
               .navigationBarHidden(true)

    }
    
    func getMsgs() {
        let db = Firestore.firestore()
        let uid = UserDefaults.standard.value(forKey: "UserName") as! String
       
        
        db.collection("Private Messages").document(uid).collection("cZQM1Io2azboEUjt42nT6k6TEDF3").order(by: "date", descending: false).addSnapshotListener { (snap, err) in
            if err != nil {
                print(err!.localizedDescription)
            }
            /*
            if snap!.isEmpty {
                
            }
            */
            for i in snap!.documentChanges{
               
                if i.type == .added{
                    let id = i.document.documentID
                    let msg = i.document.get("msg") as! String
                    let user = i.document.get("user") as! String
                    self.msgs.append(Msg(id: id, msg: msg, user: user))
                  
                }
                
               
                     
                
            }
            
    }
    }
   }

【问题讨论】:

  • 这不是 DispatchGroup() 解决的问题吗?
  • 不,您可以使用调度组在调度组为空时执行一些代码(通过notify),或者您可以wait 直到调度组为空。您正在考虑.wait 场景,但如果您确实这样做了,您将阻塞主队列并死锁整个应用程序。您需要一个模型对象来获取消息,然后发布新数据,从而刷新您的视图。

标签: ios swift firebase asynchronous swiftui


【解决方案1】:

你需要像下面这样的东西

VStack(spacing: 0){

    chatTopview()
    GeometryReader{_ in

        if self.msg.msgs.isEmpty {
           Text("Loading...")        // << some placeholder
        } else {
            chatList(msgs: self.msg.msgs)
        }
    }
}
.onAppear(){                       // << at this level !!
    if self.msg.msgs.isEmpty {
        self.getMsgs()
    }
}

并且在回调中,它是异步的,可以在后台队列中发送,最好做到以下几点

var newMsgs = [Msg]()
for i in snap!.documentChanges{

    if i.type == .added{
        let id = i.document.documentID
        let msg = i.document.get("msg") as! String
        let user = i.document.get("user") as! String
        newMsgs.append(Msg(id: id, msg: msg, user: user))
    }
}
DispatchQueue.main.async {
    self.msgs = newMsgs
}

【讨论】:

    猜你喜欢
    • 2013-09-02
    • 2020-05-12
    • 2011-03-23
    • 2018-06-14
    • 1970-01-01
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 2021-07-12
    相关资源
    最近更新 更多