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

时间:2016-10-28 17:07:04

标签: ios swift swift3 nsoperation

我试图在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()
        })

    }
}

运行它将产生:

A
B 
No errors

将其转换为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()
        }
    }
}

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

A

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

1 个答案:

答案 0 :(得分:2)

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

注释中突出显示了注释项目。

以下是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()
        }
    }
}

现在运行时会生成以下内容:

A
B
No errors