2017-02-27 4 views
1
aufgerufen wurde

Warum wird das fortgesetzt, nachdem der Beendigungshandler aufgerufen wurde?Code, der ausgeführt wird, nachdem der Vervollständigungshandler

Siehe die Kommentare im Code. Siehe den Code-Pfad, um zu # 1 zu gelangen. An dieser Stelle erwarte ich, dass der Code den Completion-Handler complete() aufruft und von der Funktion zurückkehrt, wodurch die Ausführung von # 2 verhindert wird. Code # 2 scheint jedoch immer noch ausgelöst zu werden. Irgendwelche Ideen warum dieses os auftritt?

func syncSessionLog(withCompletion complete: @escaping ((Bool, String?) -> Void)) { 

    ... bunch of code 

     managedObjectContext.performAndWait { 
      let trackFetchRequest: NSFetchRequest<NSFetchRequestResult> = Track.fetchRequest() 
      let trackPredicate = NSPredicate(format: "id == \(session.track_id)") 

      trackFetchRequest.predicate = trackPredicate 
      trackFetchRequest.fetchLimit = 1; 

      do { 
       let foundTrack = try self.managedObjectContext.fetch(trackFetchRequest) as! [Track] 
       if foundTrack.count < 1 { 
        self.debug.log(tag: "SessionManager", content: "not found tID: \(session.track_id)") 

        //#1 When not found, complete is called, yet the code still manages to reach "do stuff" down the bottom. 

        complete(false, "Not found") 
        return 
       } 

       associatedTrack = foundTrack[0] 
      } 
      catch { 
       self.debug.log(tag: "SessionManager", content: "Failed to get Track object from Core Data: \(error.localizedDescription)") 
       fatalCoreDataError(error) 
       complete(false, "Failed to retrieve") 
      } 
     } 

     //#2 do stuff with associatedTrack 
+0

Wird eine Ausnahme ausgelöst? Ihre Catch-Funktion ruft "complete" auf und kehrt nicht zurück (die Ausführung würde also zu # 2 gehen). – par

+0

return lässt Sie nur aus dem Warteblock heraus. und # 2 wird den Fluss fortsetzen. Wenn Sie die Ausführung nach dem Abschluss blockieren möchten, benötigen Sie ein boolesches Flag außerhalb der Wartefunktion. Ändern Sie den Wert gemäß Ihrer eigenen Logik und überprüfen Sie dann bei # 2 den Wert des Flags und fahren Sie fort, wenn Sie es benötigen. Vergessen Sie nicht, das Flag als Block zu deklarieren. –

+1

Nein, 'associatedTrack' wird auf Null gesetzt. :/Ich habe häcksisch gelöst, wenn ich überprüft habe, ob 'associatedTrack' gleich null ist, bevor ich weitermache. Allerdings würde ich gerne herausfinden, was hier wirklich vor sich geht. – toast

Antwort

1

return wird von dem aktuellen Kontext auszutreten, die den Verschluss mit dem performAndWait zugeordnet ist. Nachdem diese Schließung eingetreten ist, wird die Ausführung mit der nächsten Anweisung nach performAndWait fortgesetzt, was gleichbedeutend mit # 2 ist.

Sie können den Code von Punkt # 2 innerhalb der Schließung

+0

Sollte nicht dieser 'complete()' Aufruf die Ausführung stoppen, die 'Rückkehr' jemals überhaupt zu erreichen? – toast

+0

Nein 'complete' ruft den Beendigungshandler auf, aber nachdem der Beendigungshandler zurückkehrt, sind Sie nach dem Aufruf des Beendigungshandlers, der' return', wieder bei der Anweisung, aber das schließt einfach den Abschluss. – Paulw11

+1

ohhhh. Ich erwartete, einen Abschlusshandler aufzurufen, zurückzukommen sowie den Verschluss auszuführen. – toast

1

Seine ganz einfach bewegen - die return Anweisung innerhalb eines Blocks ist, so dass es aus dem Block zurückkehrt, nicht von außen Methode. Es wäre besser sichtbar, wenn der Block einen Rückgabewert hätte.

Als solche wird diese return nicht in Ihrem Code benötigt. Sie müssen ein Bool Flag setzen, um das Ergebnis der Blockausführung anzuzeigen, und entsprechend in # 2 handeln.

+0

Sollte nicht dieser 'complete()' Anruf die Ausführung davon stoppen, jemals die 'Rückkehr' überhaupt zu erreichen? – toast

+1

Nein, warum? 'complete()' ist ein weiterer Block und kein Schlüsselwort für die Sprache. Sein Name mag irreführend sein, aber es ist nur eine Namenskonvention. Es könnte sehr wohl "inform()" oder irgendetwas anderes heißen. Sie sollten an Blöcke als an Methoden denken. Du würdest nicht erwarten, dass der Code aufhört, wenn du 'self.complete()' nennst, oder? – Losiowaty

+0

Danke, ich habe dich gewählt, da ich euch beide nicht akzeptieren konnte. Vielen Dank. – toast

Verwandte Themen