swiftactoroperationqueue

Publish `operationCount` from operationQueue inside actor?


I have an actor:

actor MyActor {
    
    let theQueue = OperationQueue()

    init() {

        _ = theQueue.observe(\OperationQueue.operationCount, options: .new) { oq, change in
            print("OperationQueue.operationCount changed: \(self.theQueue.operationCount)")
        }
        
    }

    ....

}

I was trying to get a KVO going to then trigger some type of publisher call that other models in the app could subscribe to and react as needed when the operationCount changes.

I was going to have a function that maybe would set that up, but, as of now, using self in that initializer gives me this warning, which according this this:

https://forums.swift.org/t/proposal-actor-initializers-and-deinitializers/52322

it will turn into an error soon.

The warning I get is this:

Actor 'self' can only be captured by a closure from an async initializer

So, how could I trigger a publisher other models can then react to that would publish the operation queue's operationCount as it changes?


Solution

  • You don't need to capture self here. observe sends you the new value (for basically exactly this reason):

    _ = theQueue.observe(\OperationQueue.operationCount, options: .new) { oq, change in
        print("OperationQueue.operationCount changed: \(change.newValue!)")
    }
    

    Also, oq is theQueue if you need that. If you need self, the typical way to do that is:

    observation = observe(\.theQueue.operationCount, options: .new) { object, change in
        // object is `self` here.
    }
    

    Just remember that you're outside the actor inside this closure, so calls may need to be async inside a Task.