使用 Swift 3 中的操作类覆盖默认值

Cod*_*der 5 nsoperation ios swift swift3

我正在尝试使用 Swift 3 中的 Operation 类覆盖某些值,作为 2.2 转换过程的一部分,但我遇到了覆盖类属性的问题。

这是在 Swift 2.2 中正常工作的代码的简化版本:

class ViewController: UIViewController {
    lazy var operationQueue: NSOperationQueue = {
        let queue = NSOperationQueue()
        queue.maxConcurrentOperationCount = 1

        return queue
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        callOperation()
    }

    func callOperation() {
        var error: NSError?

        let words = ["A", "B"]

        words.forEach { word in
            let operation = TestOperation(text: word)
            operation.completionBlock = {
                error = operation.error
            }
            operationQueue.addOperation(operation)
        }

        operationQueue.addOperationWithBlock { 
            if error == nil {
                print("No errors")
            } else {
                print(error?.localizedDescription)
            }
        }
    }
}

class TestOperation: NSOperation {
    private(set) var error: NSError?

    private var text: String?

    private var isExecuting: Bool = false
    private var isFinished: Bool = false

    override var asynchronous: Bool {
        return true
    }

    override var executing: Bool {
        get {
            return isExecuting
        }
        set {
            willChangeValueForKey("isExecuting")
            isExecuting = newValue
            didChangeValueForKey("isExecuting")
        }
    }

    override var finished: Bool {
        get {
            return isFinished
        }
        set {
            willChangeValueForKey("isFinished")
            isFinished = newValue
            didChangeValueForKey("isFinished")
        }
    }

    init(text: String) {
        self.text = text

        super.init()
    }

    override func start() {
        if cancelled {
            finished = true

            return
        }

        executing = true

        func completeOperation() {
            finished = true
            executing = false
        }

        let dispatchTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(1.0 * Double(NSEC_PER_SEC)))
        dispatch_after(dispatchTime, dispatch_get_main_queue(), {
            print(self.text)
            completeOperation()
        })

    }
}
Run Code Online (Sandbox Code Playgroud)

运行这将产生:

A
B 
No errors
Run Code Online (Sandbox Code Playgroud)

将其转换为 Swift 3.0 后,我得到以下信息,主要问题是围绕标有注释的变量:

class ViewController: UIViewController {
    lazy var operationQueue: OperationQueue = {
        let queue = NSOperationQueue()
        queue.maxConcurrentOperationCount = 1

        return queue
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        callOperation()
    }

    func callOperation() {
        var error: NSError?

        let words = ["A", "B"]

        words.forEach { word in
            let operation = TestOperation(text: word)
            operation.completionBlock = {
                error = operation.error
            }
            operationQueue.addOperation(operation)
        }

        operationQueue.addOperationWithBlock {
            if error == nil {
                print("No errors")
            } else {
                print(error?.localizedDescription)
            }
        }
    }
}

class TestOperation: Operation {
    private(set) var error: NSError?

    private var text: String?

//    private var executing: Bool = false // Overriding var must be as accessible as its enclosing type
//    private var finished: Bool = false // Overriding var must be as accessible as its enclosing type

//    var executing: Bool = false // Cannot override a stored property
//    var finished: Bool = false // Cannot override a stored property

    override var executing: Bool = false // Cannot override a stored property
    override var finished: Bool = false // Cannot override a stored property

    override var isAsynchronous: Bool {
        return true
    }

    override var isExecuting: Bool {
        get {
            return executing
        }
        set {
            willChangeValue(forKey: "executing")
            executing = newValue
            didChangeValue(forKey: "executing")
        }
    }

    override var isFinished: Bool {
        get {
            return finished
        }
        set {
            willChangeValue(forKey: "finished")
            finished = newValue
            didChangeValue(forKey: "finished")
        }
    }

    init(text: String) {
        self.text = text

        super.init()
    }

    override func start() {
        if isCancelled {
            isFinished = true

            return
        }

        isExecuting = true

        func completeOperation() {
            isFinished = true
            isExecuting = false
        }

        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
            print(self.text)
            completeOperation()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我用其他东西(myFinished、myExecuting)替换已完成/正在执行的变量并相应地更新,我可以运行该应用程序,但我只能得到以下信息:

A
Run Code Online (Sandbox Code Playgroud)

这不允许操作正确完成,因此永远不会运行后续操作。

Cod*_*der 4

所以事实证明我需要在私有变量前面加上一个 _ 以便编译器接受它们。

值得注意的项目已用注释突出显示。

以下是 Swift 3 的工作代码:

import UIKit

class ViewController: UIViewController {
    lazy var operationQueue: OperationQueue = {
        let queue = OperationQueue()
        queue.maxConcurrentOperationCount = 1

        return queue
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        callOperation()
    }

    func callOperation() {
        var error: NSError?

        let words = ["A", "B"]

        words.forEach { word in
            let operation = TestOperation(text: word)
            operation.completionBlock = {
                error = operation.error
            }
            operationQueue.addOperation(operation)
        }

        operationQueue.addOperation {
            if error == nil {
                print("No errors")
            } else {
                print(error?.localizedDescription)
            }
        }
    }
}

class TestOperation: Operation {
    private(set) var error: NSError?

    private var text: String?

    private var _executing: Bool = false // Notice the _ before the name
    private var _finished: Bool = false // Notice the _ before the name

    override var isAsynchronous: Bool {
        return true
    }

    override var isExecuting: Bool {
        get {
            return _executing
        }
        set {
            willChangeValue(forKey: "isExecuting") // This must match the overriden variable
            _executing = newValue
            didChangeValue(forKey: "isExecuting") // This must match the overriden variable
        }
    }

    override var isFinished: Bool {
        get {
            return _finished
        }
        set {
            willChangeValue(forKey: "isFinished") // This must match the overriden variable
            _finished = newValue
            didChangeValue(forKey: "isFinished") // This must match the overriden variable
        }
    }

    init(text: String) {
        self.text = text

        super.init()
    }

    override func start() {
        if isCancelled {
            isFinished = true

            return
        }

        isExecuting = true

        func completeOperation() {
            isFinished = true
            isExecuting = false
        }

        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
            print(self.text)
            completeOperation()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在运行时会产生以下结果:

A
B
No errors
Run Code Online (Sandbox Code Playgroud)