2016-10-28 2 views
3

Ich versuche, einige Werte mit der Operation-Klasse in Swift 3 als Teil eines Konvertierungsprozesses von 2.2 zu überschreiben, aber ein Problem mit übergeordneten Klasseneigenschaften auftritt.Überschreiben von Standardwerten mit Vorgangsklasse in Swift 3

Dies ist eine vereinfachte Version des Codes, die ordnungsgemäß in Swift 2.2 funktioniert:

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() 
     }) 

    } 
} 

Lauf dies produzieren:

A 
B 
No errors 

Nachdem es zu Swift Umwandlung 3.0, erhalte ich die folgende, mit dem Hauptproblem rund um die Variablen mit Kommentaren markiert:

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() 
     } 
    } 
} 

Wenn ich ersetze e das fertige/else Variablen mit etwas Ausführung (myFinished, myExecuting) & Update dementsprechend kann ich die app laufen, aber ich nur folgenden:

A 

Dies ist nicht der Betrieb richtig, so dass nachfolgende Operationen erlaubt zu beenden werden nie ausgeführt.

Antwort

2

Es stellt sich also heraus, dass ich die privaten Variablen mit einem _ vor dem Compiler akzeptieren musste, um sie zu akzeptieren.

Die Notizelemente wurden mit Kommentaren markiert.

Unten ist der Arbeitscode für 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() 
     } 
    } 
} 

Dies nun die bei der Ausführung folgenden erzeugt:

A 
B 
No errors 
Verwandte Themen