addOperations(operations, waitUntilFinish:false)
does not implicitly retain all the operations until completion, it is essentially the same as for operation in operations { addOperation(operation) }
. Proof is below.
You may be looking at a bug with your operation where it never successfully transitions to/emits isFinished
. This seems unlikely if your operations are eventually deallocating when all of them complete.
What seems more likely is that you may have some completion code somewhere with a dependency on these operations:
- You could have a closure maintaining a reference to
operations
.
- You could have a dependent operation:
operation.addOperation(...)
- You could call
waitUntilAllOperationsAreFinished()
on the queue, which will hold a reference to the operations until they all complete.
Proof
You can prove operations are not being retained past completion with the following playground:
import Foundation
class Operation: NSOperation {
let id:Int
init(id:Int) { self.id = id }
override func main() { usleep(useconds_t(id * 100000)) }
deinit { print("Deiniting \(id)") }
}
let queue = NSOperationQueue()
do {
let operations = (0..<50).map(Operation.init)
queue.addOperations(operations, waitUntilFinished: false)
}
for i in 0..<50 {
usleep(200000)
print("Heartbeat")
}
You will see instances deallocating at regular intervals while the loop runs.
Deiniting 0
Deiniting 1
Heartbeat
Deiniting 2
Deiniting 3
Heartbeat
Deiniting 4
Deiniting 5
...