Ausführen der NSOperation, wenn alle anderen Vorgänge in NSOperationQueue beendet wurden, unabhängig davon, ob sie erfolgreich abgeschlossen wurden oder nicht

i, ich habe hier eine seltsame Situation:

Überblick

Ich arbeite an einer App, in der der Benutzer mehrere Vorgänge initiieren kann und alle diese Vorgänge in einem Hintergrundthread ausgeführt werden, sodass die Benutzeroberfläche nicht blockiert wird. Einige dieser Vorgänge sind voneinander abhängig und andere nicht. Um sicherzustellen, dass die Operation erst ausgeführt wird, nachdem alle erforderlichen Abhängigkeiten ausgeführt wurden, wird die Abhängigkeitseigenschaft von Operation verwendet. Ich benutze asynchrone Operationen.

Hier ist meine Implementierung:

import UIKit
import CoreData
import SwiftyJSON

class VMBaseOperation: NSOperation {
    var finishedStatus : Bool = false
    var executionStatus : Bool = false
    var retryCount : Int = 0
    private (set) var requestToQueue : BaseRequest? = nil
    var vmOperationCompletionBlock: ((JSON?) -> Void)?
    var vmOperationFailureBlock: ((WebResponseError?) -> Void)?

    override init() {
        super.init()
    }

    convenience init(withVMRequest request : BaseRequest) {
        self.init()
        requestToQueue = request
    }

    override func start() {
        if self.cancelled {
            self.finished = true
            return
        }
        NSThread.detachNewThreadSelector(#selector(main), toTarget: self, withObject: nil)
        self.executionStatus = true
    }


    override func main() {
        if self.cancelled {
            return
        }
        self.hitWebService()
    }

    func hitWebService(){
        let webserviceManager = WebServiceManager()
        webserviceManager.getResponseFromRequest(requestToQueue!) { (requset, response, data, error) in
            let error = WebResponseError.checkResponse(response, request: requset, error: error)
            if error != nil {
                if error == WebResponseError.NO_INTERNET {
                    if self.vmOperationFailureBlock != nil {
                        self.vmOperationFailureBlock!(error)
                    }
                    self.operationFailed()
                }
                else{
                    self.retryCount += 1
                    if self.retryCount == 3 {
                        if self.vmOperationFailureBlock != nil {
                            self.vmOperationFailureBlock!(error)
                        }
                        self.operationFailed()
                    }
                    else{
                        self.hitWebService()
                    }
                }
            }
            else{
                if data == nil {
                    self.retryCount += 1
                    if self.retryCount == 3 {
                        if self.vmOperationFailureBlock != nil {
                            self.vmOperationFailureBlock!(nil)
                        }
                        self.operationFailed()
                    }
                    else{
                        self.hitWebService()
                    }
                }
                else{
                    let json = JSON(data: data!)
                    if self.vmOperationCompletionBlock != nil {
                        self.vmOperationCompletionBlock!(json)
                    }
                    self.operationCompleted()
                }
            }
        }
    }

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

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


    override var asynchronous: Bool{
        get{
            return true
        }
        set{
            self.willChangeValueForKey("isAsynchronous")
            self.asynchronous = true
            self.didChangeValueForKey("isAsynchronous")
        }
    }

    func operationCompleted(){
        self.executing = false
        self.finished = true
    }

    func operationFailed(){
        self.executing = false
        self.finished = false
    }
}

Was es macht

ei jeder Operation wird eine Webanforderung ausgeführt, und es wird versucht, die Daten vom Server abzurufen. Wenn dies fehlschlägt, wird der Versuch dreimal ausgeführt, bevor der endgültige Status durch Aufrufen von @ auf false gesetzt wiroperationFailed -Methode und dort durch Stoppen der Ausführung aller abhängigen Operationen für immer. Wenn es andererseits erfolgreich ist, ändert es seinen Status "erledigt" in "wahr", indem es @ aufrufoperationCompleted löst daher die Ausführung der verbleibenden abhängigen Operationen aus.

Was ist das Problem

Abhängigkeit funktioniert wie ein Zauber. Kein Problem damit. Jetzt muss ich die Daten vom Server synchronisieren, wenn alle Operationen in der Operationswarteschlange beendet wurden, unabhängig davon, ob sie erfolgreich abgeschlossen wurden oder nicht.

Am einfachsten ist es, eine Operation zum Synchronisieren der Daten vom Server zu erstellen und sie als abhängige Operation zu allen Operationen hinzuzufügen, die zu operationQueue hinzugefügt wurden.

Aber aufgrund der oben genannten Art der Operation wird die Ausführung aller abhängigen Operationen (wie erwartet) auch dann angehalten, wenn eine Operation fehlschlägt. Da meine Synchronisierungsdaten von der Serveroperation jedoch ebenfalls eine abhängige Operation sind, wird sie niemals ausgeführt, selbst wenn Ein Vorgang schlägt fehl:

Was ich brauche

Während ich die oben erwähnte Abhängigkeit beibehalte, muss ich wissen, wie eine Operation ausgeführt wird, um die Daten vom Server zu synchronisieren, wenn alle Operationen in der Operationswarteschlange abgeschlossen sind, unabhängig davon, ob sie erfolgreich sind oder fehlschlagen.

Ist das überhaupt möglich :( Bitte hilf mir. Danke im Voraus.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage