Swift NSOperation内的调度组-尽管maxConcurrentOperationCount=1,但仍允许多个操作

Swift NSOperation内的调度组-尽管maxConcurrentOperationCount=1,但仍允许多个操作,swift,grand-central-dispatch,nsoperation,nsoperationqueue,Swift,Grand Central Dispatch,Nsoperation,Nsoperationqueue,我的目标是在NSOperation子类中创建一个串行下载队列,使用调度组来管理异步任务 我已将maxConcurrentOperationCount设置为1 我已经定义了我的队列 var GlobalDownloadQueue: DispatchQueue { return DispatchQueue.global(qos: DispatchQoS.QoSClass.background) } 然后在NSOperation子类的main()中,我定义了我的调度组,有3个进入和3个离开,

我的目标是在NSOperation子类中创建一个串行下载队列,使用调度组来管理异步任务

我已将maxConcurrentOperationCount设置为1

我已经定义了我的队列

var GlobalDownloadQueue: DispatchQueue {
    return DispatchQueue.global(qos: DispatchQoS.QoSClass.background)
}
然后在NSOperation子类的main()中,我定义了我的调度组,有3个进入和3个离开,然后是一个notify块

notify块似乎在正确的时间运行,但是仍然有多个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
因此,它至少使线程同步,它仍然只允许一次运行多个操作。我以为maxConcurrentOperationCount=1只允许从队列运行1个操作,直到NSOperation子类的main()函数完成为止

这就是我向队列添加项目的方式

self.downloadQueue.addOperation(DownloadOperation(index: indexPath))
然后是NSOperation中的main()函数:

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

}

GlobalOperationStore
来自哪里?