队列中的所有操作完成后立即释放 NSOperationQueue

Deallocate NSOperationQueue as soon as all operations in queue are finished

我想在所有正在进行的操作都执行完毕后释放 NSOperationQueue。 到目前为止,我已经在下面编写了代码,但据我所知 waitUntilAllOperationsAreFinished 是异步调用并且无法从我的 operationQueue 中获取 nil。

- (void)deallocOperationQueue
{
    [operationQueue waitUntilAllOperationsAreFinished];
    operationQueue = nil;
}

您可以子类化 NSOperationQueue 并观察 operations 键路径直到它达到零:

class DownloadOperationQueue: NSOperationQueue {

    private static var operationsKeyPath: String {
        return "operations"
    }

    deinit {
        self.removeObserver(self, forKeyPath: "operations")
    }

    var completionBlock: (() -> Void)? {
        didSet {
            self.addObserver(self, forKeyPath: DownloadOperationQueue.operationsKeyPath, options: .New, context: nil)
        }
    }

    override init() {
        super.init()
    }

    override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
        if let operationPath = keyPath where operationPath == DownloadOperationQueue.operationsKeyPath {
            if self.operations.count == 0 {
                NSOperationQueue.mainQueue().addOperationWithBlock({ 
                    self.completionBlock?()
                })
            }
        }
    }

}

完成时:

var operationQueue: DownloadOperationQueue? = DownloadOperationQueue()

// Add your operations ...

operationQueue?.completionBlock = {
    operationQueue = nil
}

引用 Avi

You don't need to wait for all operations to finish. Just set operationQueue to nil when you're done with it. If the queue still has operations, nothing happens to them; they will still complete.

- (void)deallocOperationQueue
{
    operationQueue = nil;
}

我已经测试了代码并确认确实发生了所述行为。