OperationQueue and dynamic priorities

I had a question about OperationQueue that I couldn’t find an easy answer to: Can you modify the priority of an operation once it’s been added to the queue?

My situation is that I have some background operations that are executing, but the user may choose to view one of these items interactively, and at that point, I’d like to bump that item’s priority so the user doesn’t have to wait for it to get its turn in the queue. I want that item to jump to the head of the line.

Many of the StackOverflow responses I looked at said that the queuePriority had to be set before the operation was added to the queue, but I couldn’t find a definitive answer in Apple’s documentation, so I put together a short playground to test it. Here’s the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import UIKit

let queue = OperationQueue()

// Serial queue, start suspended
queue.isSuspended = true
queue.maxConcurrentOperationCount = 1

// Create three operations
let operations = [
    BlockOperation() {
        print("o1")
    },
    BlockOperation() {
        print("o2")
    },
    BlockOperation() {
        print("o3")
    }
]

// Add all the operations
operations.forEach { queue.addOperation($0) }

// Resume (one of the items will start executing immediately)
queue.isSuspended = false

// Now dynamically change the priority of one of the items
operations[2].queuePriority = .high

// Must wait for competion or you won't see the result
queue.waitUntilAllOperationsAreFinished()

Play with which operation you’re adjusting the priority on and you can see the that the priority changes are respected. You can adjust the priorities of operations on a queue.