【问题标题】:Swift Dispatch Group in functionSwift Dispatch Group 在函数中
【发布时间】:2020-09-06 02:36:22
【问题描述】:

提前谢谢你。我正在使用 UITableView 并且需要在加载单元格之前创建一个数组。我正在尝试使用 DispatchGroup,我成功地创建了第一个数组,但我还需要 validPhonesNotUsingApp 的第二个数组,在同一个函数中没有创建。

我将保留整个文件的部分内容。

谢谢。

override func viewDidLoad() {
    super.viewDidLoad()
    let group = DispatchGroup()
    setUpElements()
    group.enter()
    checkContacts(group)
    group.notify(queue: .main){
            self.tableView.dataSource = self
            self.tableView.delegate = self
            self.searchBar.delegate = self
            self.tableView.keyboardDismissMode = .onDrag
            print(self.validPhonesNotUsingApp)
            self.tableView.register(TableViewCellForContacts.nib(), forCellReuseIdentifier: TableViewCellForContacts.identifier)
          }
     }


func checkContacts(_ group: DispatchGroup){
    let db = Firestore.firestore()
    db.collection("UserProfile").document(UserDataConst.UserUID).getDocument { (DocumentSnapshot1, Error1) in
        if Error1 != nil{
            print("Error finding if contacts uploaded")
            group.leave()
        }
        else{
            let hasContacts: Bool = DocumentSnapshot1?.get("Contacts Uploaded") as? Bool ?? false
            if hasContacts == true{
                db.collection("UserProfile").document(UserDataConst.UserUID).collection("ContactFriends").getDocuments { (
                    Snapshot2, Error2) in
                    if Error2 != nil{
                        group.leave()
                        return
                    }
                    else{
                        for x in 0..<Snapshot2!.documents.count{
                            group.enter()
                            let validNumber = self.correctPhoneNumber(Snapshot2!.documents[x].documentID, group)
                            if validNumber != nil{
                                self.validPhoneNumbers.append(validNumber!)
                                let first = Snapshot2!.documents[x].get("First Name") as? String ?? "(ø)"
                                self.validPhoneFirstName.append(first)
                                let last = Snapshot2!.documents[x].get("Last Name") as? String ?? "(ø)"
                                self.validPhoneLastName.append(last)
                                
                            }
                            else{
                            group.leave()
                            }
                        }

                        
                        db.collection("AllPhoneNumbers").getDocuments { (Snapshot3, Error3) in
                            if Error3 != nil{
                                group.leave()
                                return
                            }
                            else{
                                print("OK lemme know what sup")
                                let docs = Snapshot3!.documents
                                group.enter()
                                for x1 in 0..<self.validPhoneNumbers.count{
                                    group.enter()
                                    var found = false
                                    for x2 in 0..<docs.count{
                                        group.enter()
                                        if self.validPhoneNumbers[x1] == docs[x2].documentID{
                                            let uid = docs[x2].get("UID") as! String
                                            db.collection("UserProfile").document(UserDataConst.UserUID).collection("Friends").getDocuments { (QuerySnapshot4, Error4) in
                                                if Error4 != nil{
                                                    group.leave()
                                                    return
                                                }
                                                else if QuerySnapshot4!.documents.count != 0{
                                                    var found2 = false
                                                    for x3 in 0..<QuerySnapshot4!.documents.count{
                                                        group.enter()
                                                        if QuerySnapshot4!.documents[x3].documentID == uid{
                                                            found2 = true
                                                            //group.leave()
                                                            break
                                                        }
                                                        else{
                                                        group.leave()
                                                        }
                                                    }
                                         
                                                    if found2 == false{
                                                        self.UIDsUsingApp.append(uid)
                                                    }
                                                }
                                                else{
                                                    self.UIDsUsingApp.append(uid)
                                                }
                                            }
                                            //self.UIDsUsingApp.append(uid)
                                            found = true
                                            //group.leave()
                                            break
                                        }
                                    }
                                    if found == false{
                                        self.validPhonesNotUsingApp.append(self.validPhoneNumbers[x1])
                                        self.validFirstNotUsingApp.append(self.validPhoneFirstName[x1])
                                        self.validLastNotUsingApp.append(self.validPhoneLastName[x1])
                                        group.leave()
                                    }
                                    print("OK now we getting activ")
                                }
                                //print(self.UIDsUsingApp)
                            }
                        }
                        
                    }
                }
            }
            else{
                group.leave()
                return
            }
        }
    }
}

【问题讨论】:

    标签: swift grand-central-dispatch swift5


    【解决方案1】:

    我正在使用 UITableView,需要在加载单元格之前创建一个数组。我正在尝试使用 DispatchGroup

    好吧,不要。您不能在“加载单元格之前”做任何事情。不要将表处理与调度混为一谈。并且不要以这种方式使用调度组。

    关于表视图的一切都必须立即在主队列中完成。您直接在主队列的viewDidLoad 中注册。您立即在cellForRowAt: 中返回一个单元格。您不会与调度组或以任何其他方式“等待”。

    如果您要以耗时的方式为表格收集数据,那很好;在后台队列上执行,并更新您的数据模型,然后重新加载表(在主队列上)。所以:

    • 最初,如果数据尚未准备好,您的数据源方法会发现没有数据并显示一个空表。

    • 稍后,一旦您收集数据并告诉表视图重新加载,您的数据源方法会找到那里数据并显示它。

    【讨论】:

      【解决方案2】:

      一些观察:

      1. 您不想将checkContacts 的“完成处理程序”逻辑与您可能在函数中使用的调度组纠缠在一起。如果你发现自己在传递 dispatch group 对象,这通常表明你在不必要地纠缠方法。

        所以,如果您需要 checkContacts 中的调度组,可以,使用它,但不要用它来妨碍调用者。只需使用完成处理程序闭包模式即可。

      2. 确保在异步过程完成之前不更新模型对象。

      例如:

      func checkContacts(completion: @escaping (Result<[Contact], Error>) -> Void) {
          let group = DispatchGroup()
          var contacts: [Contact] = []            // in this method, we will only update this local variable
      
          ...
      
          group.notify(queue: .main) {
              if let error = error {
                  completion(.failure(error))
              } else {
                  completion(.success(contacts))  // and when we’re done, we’ll report the results
              }
          }
      }
      

      你会这样称呼它

      checkContacts { results in
          switch results {
          case .failure(let error): 
              ...
      
          case .success(let contacts):
              self.contacts = contacts            // only now will we update model properties
              ...                                 // do whatever UI updates you want, e.g.
              self.tableView.reloadData()
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-12-19
        • 2020-09-13
        • 1970-01-01
        • 2023-03-07
        • 2018-08-13
        • 2018-05-12
        • 2020-01-08
        • 2017-10-31
        相关资源
        最近更新 更多