使用 Swift 中的操作 class 覆盖默认值 3
Overriding default values with operation class in Swift 3
作为从 2.2 转换过程的一部分,我试图在 Swift 3 中使用操作 class 覆盖某些值,但遇到覆盖 class 属性的问题。
这是在 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)替换 finished/executing 变量并进行相应更新,我可以 运行 应用程序,但我只得到以下内容:
A
这不允许操作正确完成,因此后续操作永远不会 运行。
所以事实证明我需要在私有变量前加上一个 _ 以便编译器接受它们。
注意事项已用评论突出显示。
下面是 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
作为从 2.2 转换过程的一部分,我试图在 Swift 3 中使用操作 class 覆盖某些值,但遇到覆盖 class 属性的问题。
这是在 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)替换 finished/executing 变量并进行相应更新,我可以 运行 应用程序,但我只得到以下内容:
A
这不允许操作正确完成,因此后续操作永远不会 运行。
所以事实证明我需要在私有变量前加上一个 _ 以便编译器接受它们。
注意事项已用评论突出显示。
下面是 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