Charlie Fish
Charlie Fish

Reputation: 20546

Swift KVO changeHandler not being called

I have the following code to refresh multiple items. This all happens asynchronously.

func refresh(_ types: [DataTypes], callback: ((String) -> Void)?) {
    let refreshOperationQueue: OperationQueue = OperationQueue()
    let operations: [Operation] = types.map({ RefreshItem.init(type: $0) })
    refreshOperationQueue.addOperations(operations, waitUntilFinished: false)
    let _: NSKeyValueObservation = refreshOperationQueue.observe(\.operationCount) { _, _ in
        if refreshOperationQueue.operationCount == 0 {
            callback?("Success")
        }
    }
}

It reloads the data fine. But the problem is the observe changeHandler is never being called.

I'm assuming this is because that observer is being released in memory (but I could be totally wrong). If this is the case I'm not sure how to fix this in an efficient manner. If I make it a higher scope then it can only handle 1 refresh at a time, which isn't the cleanest solution.

Basically I want callback?("Success") to run when the OperationQueue is complete.

How can I achieve this?

Upvotes: 1

Views: 527

Answers (1)

Charles Srstka
Charles Srstka

Reputation: 17060

The problem is indeed that the observer is being released in memory. You need to store it somewhere. If you want to store an arbitrary number of them, just declare an array somewhere higher up in the scope, and add your observer to the array.

Alternatively, you could simply add a new BlockOperation to the operation queue, and add all your other operations as dependencies. This will cause your completion operation to run after everything else is done.

Upvotes: 2

Related Questions