-
Notifications
You must be signed in to change notification settings - Fork 134
/
OperationQueue.swift
87 lines (68 loc) · 2.82 KB
/
OperationQueue.swift
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
80
81
82
83
84
85
86
//
// OperationQueue.swift
// Operations
//
// Created by Daniel Thorpe on 26/06/2015.
// Copyright (c) 2015 Daniel Thorpe. All rights reserved.
//
import Foundation
public protocol OperationQueueDelegate: class {
func operationQueue(queue: OperationQueue, willAddOperation operation: NSOperation)
func operationQueue(queue: OperationQueue, operationDidFinish operation: NSOperation, withErrors errors: [ErrorType])
}
public class OperationQueue: NSOperationQueue {
public weak var delegate: OperationQueueDelegate? = .None
public override func addOperation(op: NSOperation) {
if let operation = op as? Operation {
// Setup an observer to invoke the delegate methods
let observer = BlockObserver(
produceHandler: { [weak self] in
self?.addOperation($1)
},
finishHandler: { [weak self] (operation, errors) in
if let q = self {
q.delegate?.operationQueue(q, operationDidFinish: operation, withErrors: errors)
}
}
)
operation.addObserver(observer)
let dependencies = operation.conditions.flatMap {
flatMap($0.dependencyForOperation(operation), { [$0] }) ?? []
}
for dependency in dependencies {
operation.addDependency(dependency)
addOperation(dependency)
}
// Check for exclusive mutability constraints
let concurrencyCategories: [String] = operation.conditions.flatMap {
flatMap($0) {
if !$0.isMutuallyExclusive { return .None }
return ["\($0.dynamicType)"]
} ?? []
}
if !concurrencyCategories.isEmpty {
let manager = ExclusivityManager.sharedInstance
manager.addOperation(operation, categories: concurrencyCategories)
operation.addObserver(BlockObserver(finishHandler: { (operation, _) in
manager.removeOperation(operation, categories: concurrencyCategories)
}))
}
// Indicate to the operation that it is to be enqueued
operation.willEnqueue()
}
else {
op.addCompletionBlock { [weak self, weak op] in
if let queue = self, let op = op {
queue.delegate?.operationQueue(queue, operationDidFinish: op, withErrors: [])
}
}
}
delegate?.operationQueue(self, willAddOperation: op)
super.addOperation(op)
}
public override func addOperations(ops: [AnyObject], waitUntilFinished wait: Bool) {
if let ops = ops as? [NSOperation] {
ops.map(addOperation)
}
}
}