我已经将NSOperation子类化为尝试在串行队列中运行一些异步任务,但是,尽管我努力使用信号量和调度组,但NSOperationQueue仍然允许多个操作同时运行。我设置了maxConcurrentOperationCount = 1。
在下面的代码中,我设置了我的调度组,它们确实使代码顺序运行。
如果我运行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
如果我运行2个操作控制台打印:
[0, 1] : Enter : 1
[0, 0] : Enter : 2
[0, 1] : Enter : 2
[0, 0] : Enter : 3
[0, 0] : Leave : 1
[0, 0] : Leave : 2
[0, 0] : Leave : 3
QUEUE FINISHED
[0, 1] : Enter : 3
[0, 1] : Leave : 1
[0, 1] : Leave : 2
[0, 1] : Leave : 3
QUEUE FINISHED
无法理解......
override func main() {
GlobalDownloadQueue.async() {
if(self.isCancelled) {
return
}
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
// let semaphore = DispatchSemaphore(value: 0)
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 {
// only reload if vc visible
if (DownloadCollectionController().isViewLoaded && (DownloadCollectionController().view.window != nil)) {
self.mainQueue.addOperation {
// reload the cell
self.collectionView.reloadItems(at: [self.indexPath])
self.collectionCell.isUserInteractionEnabled = true
}
}
//semaphore.signal()
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")
}
})
}
//downloadGroup.enter() // add task 4
//print("\(self.indexPath) : Enter : 4")
}, 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
}
}
})
}
}
//semaphore.wait()
downloadGroup.notify(queue: GlobalDownloadQueue, execute: {
print("QUEUE FINISHED")
})
} // async
} // main