Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save boudhayan/d4716b41c077d0aa05b82f3007c552e8 to your computer and use it in GitHub Desktop.

Select an option

Save boudhayan/d4716b41c077d0aa05b82f3007c552e8 to your computer and use it in GitHub Desktop.

Revisions

  1. @calebd calebd renamed this gist Apr 11, 2017. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. @calebd calebd revised this gist Apr 10, 2017. 1 changed file with 5 additions and 1 deletion.
    6 changes: 5 additions & 1 deletion ConcurrentOperation.swift
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@ import Foundation
    /// Subclasses must implement `execute()` to perform any work and call
    /// `finish()` when they are done. All `NSOperation` work will be handled
    /// automatically.
    open class Operation: Foundation.Operation {
    open class AsynchronousOperation: Operation {

    // MARK: - Properties

    @@ -38,6 +38,10 @@ open class Operation: Foundation.Operation {
    public final override var isFinished: Bool {
    return state == .finished
    }

    public final override var isAsynchronous: Bool {
    return true
    }


    // MARK: - NSObject
  3. @calebd calebd revised this gist Dec 8, 2016. 1 changed file with 6 additions and 2 deletions.
    8 changes: 6 additions & 2 deletions ConcurrentOperation.swift
    Original file line number Diff line number Diff line change
    @@ -8,7 +8,9 @@ open class Operation: Foundation.Operation {

    // MARK: - Properties

    private let stateQueue = DispatchQueue(label: "com.calebd.operation.state")
    private let stateQueue = DispatchQueue(
    label: "com.calebd.operation.state",
    attributes: .concurrent)

    private var rawState = OperationState.ready

    @@ -18,7 +20,9 @@ open class Operation: Foundation.Operation {
    }
    set {
    willChangeValue(forKey: "state")
    stateQueue.sync(execute: { rawState = newValue })
    stateQueue.sync(
    flags: .barrier,
    execute: { rawState = newValue })
    didChangeValue(forKey: "state")
    }
    }
  4. @calebd calebd revised this gist Dec 8, 2016. 1 changed file with 3 additions and 1 deletion.
    4 changes: 3 additions & 1 deletion ConcurrentOperation.swift
    Original file line number Diff line number Diff line change
    @@ -71,7 +71,9 @@ open class Operation: Foundation.Operation {
    /// Subclasses must implement this to perform their work and they must not
    /// call `super`. The default implementation of this function throws an
    /// exception.
    open func execute() {}
    open func execute() {
    fatalError("Subclasses must implement `execute`.")
    }

    /// Call this function after any work is done or after a call to `cancel()`
    /// to move the operation into a completed state.
  5. @calebd calebd revised this gist Dec 8, 2016. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ConcurrentOperation.swift
    Original file line number Diff line number Diff line change
    @@ -8,7 +8,7 @@ open class Operation: Foundation.Operation {

    // MARK: - Properties

    private let stateQueue = DispatchQueue(label: "com.courtneycircle.radiant.operation.state")
    private let stateQueue = DispatchQueue(label: "com.calebd.operation.state")

    private var rawState = OperationState.ready

  6. @calebd calebd revised this gist Dec 8, 2016. 1 changed file with 76 additions and 49 deletions.
    125 changes: 76 additions & 49 deletions ConcurrentOperation.swift
    Original file line number Diff line number Diff line change
    @@ -1,60 +1,87 @@
    //
    // ConcurrentOperation.swift
    //
    // Created by Caleb Davenport on 7/7/14.
    //
    // Learn more at http://blog.calebd.me/swift-concurrent-operations
    //

    import Foundation

    class ConcurrentOperation: NSOperation {

    // MARK: - Types

    enum State {
    case Ready, Executing, Finished
    func keyPath() -> String {
    switch self {
    case Ready:
    return "isReady"
    case Executing:
    return "isExecuting"
    case Finished:
    return "isFinished"
    }
    }
    }

    /// An abstract class that makes building simple asynchronous operations easy.
    /// Subclasses must implement `execute()` to perform any work and call
    /// `finish()` when they are done. All `NSOperation` work will be handled
    /// automatically.
    open class Operation: Foundation.Operation {

    // MARK: - Properties

    var state = State.Ready {
    willSet {
    willChangeValueForKey(newValue.keyPath())
    willChangeValueForKey(state.keyPath())

    private let stateQueue = DispatchQueue(label: "com.courtneycircle.radiant.operation.state")

    private var rawState = OperationState.ready

    @objc private dynamic var state: OperationState {
    get {
    return stateQueue.sync(execute: { rawState })
    }
    didSet {
    didChangeValueForKey(oldValue.keyPath())
    didChangeValueForKey(state.keyPath())
    set {
    willChangeValue(forKey: "state")
    stateQueue.sync(execute: { rawState = newValue })
    didChangeValue(forKey: "state")
    }
    }

    // MARK: - NSOperation

    override var ready: Bool {
    return super.ready && state == .Ready

    public final override var isReady: Bool {
    return state == .ready && super.isReady
    }

    public final override var isExecuting: Bool {
    return state == .executing
    }
    override var executing: Bool {
    return state == .Executing

    public final override var isFinished: Bool {
    return state == .finished
    }

    override var finished: Bool {
    return state == .Finished


    // MARK: - NSObject

    @objc private dynamic class func keyPathsForValuesAffectingIsReady() -> Set<String> {
    return ["state"]
    }
    override var asynchronous: Bool {
    return true

    @objc private dynamic class func keyPathsForValuesAffectingIsExecuting() -> Set<String> {
    return ["state"]
    }


    @objc private dynamic class func keyPathsForValuesAffectingIsFinished() -> Set<String> {
    return ["state"]
    }


    // MARK: - Foundation.Operation

    public override final func start() {
    super.start()

    if isCancelled {
    finish()
    return
    }

    state = .executing
    execute()
    }


    // MARK: - Public

    /// Subclasses must implement this to perform their work and they must not
    /// call `super`. The default implementation of this function throws an
    /// exception.
    open func execute() {}

    /// Call this function after any work is done or after a call to `cancel()`
    /// to move the operation into a completed state.
    public final func finish() {
    state = .finished
    }
    }

    @objc private enum OperationState: Int {
    case ready
    case executing
    case finished
    }
  7. @calebd calebd revised this gist Mar 3, 2015. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ConcurrentOperation.swift
    Original file line number Diff line number Diff line change
    @@ -42,7 +42,7 @@ class ConcurrentOperation: NSOperation {
    // MARK: - NSOperation

    override var ready: Bool {
    return state == .Ready
    return super.ready && state == .Ready
    }

    override var executing: Bool {
  8. @calebd calebd revised this gist Mar 3, 2015. 1 changed file with 1 addition and 8 deletions.
    9 changes: 1 addition & 8 deletions ConcurrentOperation.swift
    Original file line number Diff line number Diff line change
    @@ -28,7 +28,7 @@ class ConcurrentOperation: NSOperation {

    // MARK: - Properties

    var state: State {
    var state = State.Ready {
    willSet {
    willChangeValueForKey(newValue.keyPath())
    willChangeValueForKey(state.keyPath())
    @@ -39,13 +39,6 @@ class ConcurrentOperation: NSOperation {
    }
    }

    // MARK: - Initializers

    init() {
    state = State.Ready
    super.init()
    }

    // MARK: - NSOperation

    override var ready: Bool {
  9. @calebd calebd revised this gist Jul 18, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ConcurrentOperation.swift
    Original file line number Diff line number Diff line change
    @@ -64,4 +64,4 @@ class ConcurrentOperation: NSOperation {
    return true
    }

    }
    }
  10. @calebd calebd revised this gist Jul 18, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion ConcurrentOperation.swift
    Original file line number Diff line number Diff line change
    @@ -60,7 +60,7 @@ class ConcurrentOperation: NSOperation {
    return state == .Finished
    }

    override var concurrent: Bool {
    override var asynchronous: Bool {
    return true
    }

  11. @calebd calebd renamed this gist Jul 7, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion gistfile1.txt → ConcurrentOperation.swift
    Original file line number Diff line number Diff line change
    @@ -3,7 +3,7 @@
    //
    // Created by Caleb Davenport on 7/7/14.
    //
    // Learn more at <link>
    // Learn more at http://blog.calebd.me/swift-concurrent-operations
    //

    import Foundation
  12. @calebd calebd revised this gist Jul 7, 2014. 1 changed file with 6 additions and 2 deletions.
    8 changes: 6 additions & 2 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    //
    // Operation.swift
    // ConcurrentOperation.swift
    //
    // Created by Caleb Davenport on 7/7/14.
    //
    @@ -8,7 +8,7 @@

    import Foundation

    class Operation: NSOperation {
    class ConcurrentOperation: NSOperation {

    // MARK: - Types

    @@ -60,4 +60,8 @@ class Operation: NSOperation {
    return state == .Finished
    }

    override var concurrent: Bool {
    return true
    }

    }
  13. @calebd calebd created this gist Jul 7, 2014.
    63 changes: 63 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,63 @@
    //
    // Operation.swift
    //
    // Created by Caleb Davenport on 7/7/14.
    //
    // Learn more at <link>
    //

    import Foundation

    class Operation: NSOperation {

    // MARK: - Types

    enum State {
    case Ready, Executing, Finished
    func keyPath() -> String {
    switch self {
    case Ready:
    return "isReady"
    case Executing:
    return "isExecuting"
    case Finished:
    return "isFinished"
    }
    }
    }

    // MARK: - Properties

    var state: State {
    willSet {
    willChangeValueForKey(newValue.keyPath())
    willChangeValueForKey(state.keyPath())
    }
    didSet {
    didChangeValueForKey(oldValue.keyPath())
    didChangeValueForKey(state.keyPath())
    }
    }

    // MARK: - Initializers

    init() {
    state = State.Ready
    super.init()
    }

    // MARK: - NSOperation

    override var ready: Bool {
    return state == .Ready
    }

    override var executing: Bool {
    return state == .Executing
    }

    override var finished: Bool {
    return state == .Finished
    }

    }