繁体   English   中英

为什么这个 function append object 每次运行时都会两次到阵列?

[英]Why does this function append the object twice to the array each time it runs?

我正在使用 swift 的 DispatchGroup() 来帮助编排一个 for 循环

  • 在 firesbase 中找到一个文档
  • 将文档转换为自定义 object
  • 将自定义 object 附加到数组

每次通过时,function 最终都会将每个 object 两次附加到数组中,我不明白为什么。 这里是 function...

    func getFriends() {
    
    // Initialize the DispatchGroup
    let group = DispatchGroup()

    // the myFriends array contains documentIDs that I am using to fetch documents from firebase
    //
    for pid in myFriendObj.myFriends {
        group.enter()
        
        _ = Firestore.firestore().collection("Players")
            .whereField(FieldPath.documentID(), isEqualTo:  pid)
            .addSnapshotListener { [self] querySnapshot, error in

                if let error = error {
                    print("Error getting > Players: \(error.localizedDescription)")
                    return
                }
                guard let querySnapshot = querySnapshot else { return }

                self.players.append(
                    contentsOf: querySnapshot.documents.compactMap { document in
                    try? document.data(as: UserProfile.self)
                })
           
                group.leave()
                
         }
    }
    
    group.notify(queue: DispatchQueue.global(qos: .background)) {
        // I'm currently eliminating the dups via this fancy extends method.
        self.players = self.players.removeDuplicates()
    }
    
}

:: 更新::

仍然没有运气 - 我什至删除了 dispatchgroup 和 snapshotlistener 回调,当 class 的实例被实例化时,这段代码仍然调用 get() 两次。 这是新的,更简单的代码......

class FriendRepository: ObservableObject {

private    let store = Firestore.firestore()
private    let friendPath: String = "MyFriends"
@Published var friendIDs: [String] = []

var userId = ""

private let authenticationService = AuthenticationService()
private var cancellables: Set<AnyCancellable> = []


init() {
    authenticationService.$user
        .compactMap { user in
            user?.uid
        }
        .assign(to: \.userId, on: self)
        .store(in: &cancellables)

    authenticationService.$user
        .receive(on: DispatchQueue.main)
        .sink { [weak self] _ in
            self?.get()
        }
        .store(in: &cancellables)
}


 

func get( ) {
    store.collection(friendPath).document(userId).getDocument {(document, error) in
        let result = Result {
          try document?.data(as: Friends.self)
        }
        switch result {
        case .success(let f):
            if let f = f {
                print("friends:>> \(f.myFriends)")
                self.friendIDs = f.myFriends
            } else {
                print("Document does not exist")
            }
        case .failure(let error):
            print("Error decoding city: \(error)")
        }
    }
}

当一个新实例运行 init() 时,我在控制台中看到了这个...它打印了 friends:>> 语句两次

friends:>> ["PHyUe6mAc3LodM5guJJU"]
friends:>> ["PHyUe6mAc3LodM5guJJU"]

每次数据库中发生更改时,您的addSnapshotListener闭包都会使用与查询匹配的所有数据调用 - 即使该数据自上次调用以来没有更改。 这通常意味着您需要在回调顶部清空self.players ,或者循环遍历documentChanges集合以确定更改的确切内容。

    func getFriends() {
// this will empty the players array when ever the get friends function gets called. 
self.players.removeAll()
// Initialize the DispatchGroup
let group = DispatchGroup()

// the myFriends array contains documentIDs that I am using to fetch documents from firebase
//
for pid in myFriendObj.myFriends {
    group.enter()
    
    _ = Firestore.firestore().collection("Players")
        .whereField(FieldPath.documentID(), isEqualTo:  pid)
        .addSnapshotListener { [self] querySnapshot, error in

            if let error = error {
                print("Error getting > Players: \(error.localizedDescription)")
                return
            }
            guard let querySnapshot = querySnapshot else { return }

            self.players.append(
                contentsOf: querySnapshot.documents.compactMap { document in
                try? document.data(as: UserProfile.self)
            })
       
            group.leave()
   
     }
}

}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM