-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathExclusivityController.swift
More file actions
79 lines (62 loc) · 2.73 KB
/
ExclusivityController.swift
File metadata and controls
79 lines (62 loc) · 2.73 KB
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/*
Copyright (C) 2015 Apple Inc. All Rights Reserved.
See LICENSE.txt for this sample’s licensing information
Abstract:
The file contains the code to automatically set up dependencies between mutually exclusive operations.
*/
import Foundation
/**
`ExclusivityController` is a singleton to keep track of all the in-flight
`Operation` instances that have declared themselves as requiring mutual exclusivity.
We use a singleton because mutual exclusivity must be enforced across the entire
app, regardless of the `OperationQueue` on which an `Operation` was executed.
*/
class ExclusivityController {
static let sharedExclusivityController = ExclusivityController()
private let serialQueue = dispatch_queue_create("Operations.ExclusivityController", DISPATCH_QUEUE_SERIAL)
private var operations: [String: [Operation]] = [:]
private init() {
/*
A private initializer effectively prevents any other part of the app
from accidentally creating an instance.
*/
}
/// Registers an operation as being mutually exclusive
func addOperation(operation: Operation, categories: [String]) {
/*
This needs to be a synchronous operation.
If this were async, then we might not get around to adding dependencies
until after the operation had already begun, which would be incorrect.
*/
dispatch_sync(serialQueue) {
for category in categories {
self.noqueue_addOperation(operation, category: category)
}
}
}
/// Unregisters an operation from being mutually exclusive.
func removeOperation(operation: Operation, categories: [String]) {
dispatch_async(serialQueue) {
for category in categories {
self.noqueue_removeOperation(operation, category: category)
}
}
}
// MARK: Operation Management
private func noqueue_addOperation(operation: Operation, category: String) {
var operationsWithThisCategory = operations[category] ?? []
if let last = operationsWithThisCategory.last {
operation.addDependency(last)
}
operationsWithThisCategory.append(operation)
operations[category] = operationsWithThisCategory
}
private func noqueue_removeOperation(operation: Operation, category: String) {
let matchingOperations = operations[category]
if var operationsWithThisCategory = matchingOperations,
let index = operationsWithThisCategory.indexOf(operation) {
operationsWithThisCategory.removeAtIndex(index)
operations[category] = operationsWithThisCategory
}
}
}