от?
емлюсь к очереди последовательной загрузки в подклассе NSOperation с использованием групп диспетчеризации для управления асинхронными задачами.
У меня maxConcurrentOperationCount установлен в 1
я определил свою очередь
var GlobalDownloadQueue: DispatchQueue {
return DispatchQueue.global(qos: DispatchQoS.QoSClass.background)
}
Затем внутри main () подкласса NSOperation я определил мою группу рассылки, имею 3 входа и 3 выхода, затем блок уведомления.
Кажется, что блок уведомлений работает в нужное время, однако все еще одновременно выполняется несколько экземпляров NSOperation.
Это то, что печатает консоль, когда я выбираю 2 загрузки.
[0, 3] : Enter : 1
[0, 2] : Enter : 2
[0, 3] : Enter : 2
[0, 2] : Enter : 3
[0, 2] : Leave : 1
[0, 2] : Leave : 2
QUEUE FINISHED
[0, 2] : Leave : 3
[0, 3] : Enter : 3
[0, 3] : Leave : 1
[0, 3] : Leave : 2
[0, 3] : Leave : 3
QUEUE FINISHED
Вот как это выглядит, когда я выбираю 1 скачать:
[0, 0] : Enter : 1
[0, 0] : Enter : 2
[0, 0] : Enter : 3
[0, 0] : Leave : 1
[0, 0] : Leave : 2
[0, 0] : Leave : 3
QUEUE FINISHED
Таким образом, он, по крайней мере, делает поток синхронным, позволяя запускать более 1 операции одновременно. Я думал, что maxConcurrentOperationCount = 1 позволит только 1 операции из очереди, пока функция main () подкласса NSOperation не будет завершена?
Вот так я добавляю предметы в очередь
self.downloadQueue.addOperation(DownloadOperation(index: indexPath))
И тогда моя функция main () внутри NSOperation:
override func main() {
// this is async because using the enter and leave should make it essentially serial??
GlobalDownloadQueue.async() {
let downloadGroup = DispatchGroup()
let downloadedAudio = PFObject(className: "downloadedAudio")
let selectedObjectId = GlobalOperationStore.sharedInstance.globalMultiPartArray[self.collectionView.tag][self.indexPath.item].id
let selectedPartName = GlobalOperationStore.sharedInstance.globalMultiPartArray[self.collectionView.tag][self.indexPath.item].name
downloadGroup.enter() // add task 1
print("\(self.indexPath) : Enter : 1")
let query = PFQuery(className: "Part")
query.whereKey("objectId", equalTo: selectedObjectId)
query.getFirstObjectInBackground { (object, error) in
if error != nil || object == nil {
print("No object for the index selected.")
//downloadGroup.leave() // remove task 1 if error with query
} else {
//print("there is an object, getting the file.")
downloadedAudio.add(object?.object(forKey: "partAudio") as! PFFile, forKey: selectedPartName)
let downloadedFile = object?.object(forKey: "partAudio") as! PFFile
downloadGroup.enter() // add task 2
print("\(self.indexPath) : Enter : 2")
// get the data first so we can track progress
downloadedFile.getDataInBackground({ (success, error) in
if (success != nil) {
downloadGroup.enter() // add task 3
print("\(self.indexPath) : Enter : 3")
// pin the audio if there is data
downloadedAudio.pinInBackground(block: { (success, error) in
if success {
//if (DownloadCollectionController().isViewLoaded && (DownloadCollectionController().view.window != nil)) {
// viewController is visible
/// maybe has to be operation main queue
self.mainQueue.addOperation {
// reload the cell
self.collectionView.reloadItems(at: [self.indexPath])
self.collectionCell.isUserInteractionEnabled = true
}
downloadGroup.leave() // remove task 1 when complete
print("\(self.indexPath) : Leave : 1")
downloadGroup.leave() // remove task 2 when complete
print("\(self.indexPath) : Leave : 2")
downloadGroup.leave() // remove task 3 when complete
print("\(self.indexPath) : Leave : 3")
//}
}
})
}
}, progressBlock: { (percent) in
self.mainQueue.addOperation {
//print("\(downloadedFile.name)::::\(percent)")
//self.activityIndicatorView.stopAnimating()
if let downloadingCell = self.collectionView.cellForItem(at: self.indexPath) as? InnerCollectionCell {
downloadingCell.progressBar.isHidden = false
downloadingCell.contentView.bringSubview(toFront: downloadingCell.progressBar)
downloadingCell.progressBar.setProgress(Float(percent) / Float(100), animated: true)
downloadingCell.setNeedsDisplay()
downloadingCell.isUserInteractionEnabled = false
}
}
})
}
}
downloadGroup.notify(queue: GlobalDownloadQueue, execute: {
print("QUEUE FINISHED")
})
} // async
}