Skip to content

Instantly share code, notes, and snippets.

@patricklynch
Last active August 29, 2015 14:27
Show Gist options
  • Save patricklynch/acac29cf7f44c60f644b to your computer and use it in GitHub Desktop.
Save patricklynch/acac29cf7f44c60f644b to your computer and use it in GitHub Desktop.
NSOperation Subclass
/// An NSOperation subclass with utilities for creating long-running operations or
/// operations that must pause and wait for some result, as well as a concise API
/// to make them easy to create, configure and add to background and main queues.
class Operation: NSOperation {
/// Shared background queue
static let backgroundQueue: NSOperationQueue = {
var queue = NSOperationQueue()
queue.maxConcurrentOperationCount = 5
return queue
}()
private var _executing = false
private var _finished = false
/// Subclasses that do not implement `main()` and need to maintain excuting state call this to move into an excuting state.
func beganExecuting () {
executing = true
finished = false
}
/// Subclasses that do not implement `main()` and need to maintain excuting state call this to move out of an executing state and are finished doing work.
func finishedExecuting () {
executing = false
finished = true
}
var mainQueueCompletionBlock: (()->())? {
didSet {
if let completion = self.mainQueueCompletionBlock {
self.completionBlock = {
dispatch_async( dispatch_get_main_queue(), completion )
}
}
}
}
func queue( completion: (()->())? = nil ) {
self.mainQueueCompletionBlock = completion
dispatch_async( dispatch_get_main_queue() ) {
NSOperationQueue.mainQueue().addOperation( self )
}
}
func queueInBackground( completion: (()->())? = nil ) {
self.mainQueueCompletionBlock = completion
dispatch_async( dispatch_get_main_queue() ) {
Operation.backgroundQueue.addOperation( self )
}
}
// MARK: - KVO-able NSNotification State
override var executing : Bool {
get {return _executing }
set {
willChangeValueForKey("isExecuting")
_executing = newValue
didChangeValueForKey("isExecuting")
}
}
override var finished : Bool {
get {return _finished }
set {
willChangeValueForKey("isFinished")
_finished = newValue
didChangeValueForKey("isFinished")
}
}
}
// MARK: - Usage exaples
// Main queue
MyOperation().queue() {
print( "Main thread operation complete." )
}
// Background queue (with main queue completion closure)
MyOperation().queueInBackground() {
print( "Background operation complete." )
}
// Using a custom queue as normal
var myQueue = NSOperationQueue()
let operation = MyOperation()
operation.mainQueueCompletionBlock = {
print( "Background operation complete." )
}
myQueue.addOperation( operation )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment