How is one supposed to aggregate data when using Grand Central Dispatch's ConcurrentPerform()?

I am doing what is in the code below, but resultDictionary seems to lose all its data when the notify() block ends. Thus all I get is an empty dictionary that is returned from the function.

I am not sure why this is happening, because when I print or set a breakpoint I can see there is something in the resultDictionary before the block ends.

```
    let getCVPDispatchQueue = DispatchQueue(label: "blarg",
                                        qos: .userInitiated,
                                        attributes: .concurrent)
    let getCVPDispatchGroup = DispatchGroup()

    var resultDictionary = dataIDToSRLParticleDictionary()

    getCVPDispatchQueue.async { [weak self] in
        guard let self = self else { return }
        DispatchQueue.concurrentPerform(iterations: self.dataArray.count) { [weak self] (index) in
            guard let self = self else { return }
            let data = self.dataArray[index]
            getCVPDispatchGroup.enter()
            let theResult = data.runPartcleFilterForClosestParticleAndMaybeStopAudio()
            switch theResult {
                case .success(let CVParticle):
                    // If there was a CVP found, add it to the set.
                    if let theCVParticle = CVParticle {
                        self.dataIDsToCVPDictionary.addTodataIDToCVPDict(key: data.ID,
                                                                            value: theCVParticle)
                    }
                case .failure(let error):
                    os_log(.error, log: self.logger, "rundatasProcessing error: %s", error.localizedDescription)
                    self._isActive = false
            }
            getCVPDispatchGroup.leave()
        }

        getCVPDispatchGroup.notify(queue: .main) { [weak self] in
            guard let self = self else { return }
            print("DONE with \(self.dataIDsToCVPDictionary.getDictionary.count)")
            resultDictionary = self.dataIDsToCVPDictionary.getDictionary
            print("resultDictionary has \(self.dataIDsToCVPDictionary.getDictionary.count)")
        }

    }

    print("Before Return  with \(resultDictionary.count)")

    return resultDictionary

}

```

Not sure if this will help, but this is simple class I made to made accessing the dictionary thread safe.

```
class DATASynchronizedIDToParticleDictionary {
    var unsafeDictionary: DATAIDToDATAParticleDictionary = DATAIDToDATAParticleDictionary()
    let accessQueue = DispatchQueue(label: "blarg2",
                                    qos: .userInitiated,
                                    attributes: .concurrent)
    var getDictionary: DATAIDToDATAParticleDictionary {
        get {
            var dictionaryCopy: DATAIDToDATAParticleDictionary!
            accessQueue.sync {
                dictionaryCopy = unsafeDictionary
            }
            return dictionaryCopy
        }
    }
    func addToDATAIDToCVPDict(key: String, value: DATAParticle) {
        accessQueue.async(flags: .barrier) { [weak self] in
            guard let self = self else { return }
            self.unsafeDictionary[key] = value
        }
    }
    func clearDictionary() {
        accessQueue.async(flags: .barrier) { [weak self] in
            guard let self = self else { return }
            self.unsafeDictionary.removeAll()
        }
    }
}

```