2016-02-12 16 views
5

Ich versuche loadViews() nach dem pullData() abgeschlossen ist und ich frage mich, was der beste Weg, dies zu tun, ist zu laufen? Ich möchte auch ein Timeout von 10 Sekunden einstellen, damit ich einen Netzwerkfehler anzeigen kann, wenn möglich. Nach dem, was ich gelesen habe, sieht GCD aus, als wäre es der Weg, um dies zu erreichen, aber ich bin bei der Implementierung davon verwirrt. Danke für jede Hilfe, die Sie geben können!Ausführen einer Funktion nach dem anderen schließt

//1 
pullData() 
//2 
loadViews() 
+7

sollten Sie vielleicht einfach in loadViews als Callback/Completion-Block an pullData übergeben, so dass pullData immer dann entscheidet, wenn das Ziehen abgeschlossen ist zündete. – luk2302

+0

Wie gehe ich dabei vor? Kann ich auch einen Timer implementieren, wenn ich diesen Weg gehe? – Opei

+2

Wenn Sie beispielsweise nach "swift completion block" suchen, ist Ihre Frage in der Regel zu weit gefasst und wird vor allem auf meinungsbezogene Antworten wie meinen Kommentar stoßen. Du müsstest viel mehr Kontext zeigen, erklären * genau * was du erreichen willst: ein Timer oder ein Lauf, nachdem er abgeschlossen ist, sind ziemlich genau das Gegenteil von einander. Außerdem sollten Sie zeigen, was Sie bisher versucht haben. – luk2302

Antwort

9

Was Sie brauchen, ist ein Abschluss-Handler mit einem Abschluss-Block.

Es ist wirklich einfach zu erstellen:

func firstTask(completion: (success: Bool) -> Void) { 
    // Do something 

    // Call completion, when finished, success or faliure 
    completion(success: true) 
} 

und verwenden Sie Ihre Abschluss-Block wie folgt aus:

firstTask { (success) -> Void in 
    if success { 
     // do second task if success 
     secondTask() 
    } 
} 
+0

Das sieht gut aus. Danke für das Teilen. Würde dies ein Timeout-Problem behandeln? Gibt es eine Art eingebauter Timeout-Abschlussblöcke? – Opei

+1

Wenn es ein Zeitlimit gibt, wie wenn Sie Daten aus dem Internet abrufen, dann rufen Sie nur die Vervollständigung mit dem Fehler 'completion (Erfolg: false)' auf. Der Completion-Block wird nicht automatisch ausgelöst, wenn er nicht aufgerufen wird. Sie können jedoch in Ihrer firstTask noch einen Timer hinzufügen, um zu überprüfen, ob nach xx Sekunden immer noch keine Ergebnisse vorliegen. –

+0

Ok super danke! – Opei

2

Ich hatte eine ähnliche Situation, in der ich eine Ansicht initalisieren musste, sobald die Daten vom Parse-Server abgerufen wurden. Früher habe ich die folgenden:

func fetchQuestionBank(complete:()->()){ 

     let userDefault = NSUserDefaults.standardUserDefaults() 
     let username = userDefault.valueForKey("user_email") as? String 

     var query = PFQuery(className:"QuestionBank") 
     query.whereKey("teacher", equalTo: username!) 

     query.findObjectsInBackgroundWithBlock { (objects:[AnyObject]?, error:NSError?) -> Void in 

      if error == nil { 
       if let objects = objects as? [PFObject] { 

        var questionTitle:String? 
        var options:NSArray? 

        for (index, object) in enumerate(objects) { 

         questionTitle = object["question_title"] as? String 
         options = object["options"] as? NSArray 
         var aQuestion = MultipleChoiceQuestion(questionTitle: questionTitle!, options: options!) 
         aQuestion.questionId = object.objectId! 
         InstantlyModel.sharedInstance.questionBank.append(aQuestion) 
        } 


        complete() 
       } 
      }else{ 
       println(" Question Bank Error \(error) ") 
      } 
     } 
    } 

und das ist die Methode nennen:

self.fetchQuestionBank({() ->() in 
         //Once all the data pulled from server. Show Teacher View. 
         self.teacherViewController = TeacherViewController(nibName: "TeacherViewController", bundle: nil) 
         self.view.addSubview(self.teacherViewController!.view) 
        }) 
2

Sie mögen dies erreichen können: -

func demo(completion: (success: Bool) -> Void) { 
    // code goes here 
    completion(success: true) 
} 
Verwandte Themen