我试图在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
这不允许操作正确完成,因此后续操作永远不会运行。
答案 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