3

I have lots of UIImage batching operations. I add them in once with in an instance of NSOperationQueue :

self.operationQueue.addOperations(operations, waitUntilFinished: false)

But it seems operationQueue captures all the operations and release them after all of them are finished.

My operation instances inherite from this class

How can I release an operation that just finished ? Am I missing something ?

Pierre
  • 10,593
  • 5
  • 50
  • 80

1 Answers1

4

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
...
Brian Nickel
  • 26,890
  • 5
  • 80
  • 110