0

Ich habe 2 grundlegende Methoden - viewDidLoad und viewDidAppear. Gemäß meiner App-Philosophie ruft der View-Controller beim Laden von Daten Daten von der Basis ab und beginnt sie mit einigen Prädikaten zu sortieren. Der Abholvorgang ist lang, also habe ich ihn in die globale Warteschlange geschickt. Wenn meine Ansicht erscheint, erhält sie offensichtlich nicht den Wert von array (der in load-Methode kompiliert wird) und stürzt ab. Also muss ich viewDidAppear warten, bis mindestens ein Objekt an Array angehängt wird. Art von Semaphoren oder Temp-Werten? Vielen Dank im Voraus!Einfaches Warten auf Wert aus asynchronem Thread

P.S. Jedes Element in einem Array repräsentiert eine Struktur mit Daten, die eine Benutzeroberfläche bilden. Der Benutzer interagiert mit dieser Benutzerschnittstelle, daher muss er einmal mit dem ersten Element aus dem Array geladen werden. Um zum nächsten Element zu wechseln, klickt der Benutzer einfach auf "Weiter" und die Benutzeroberfläche ändert sich entsprechend dem nächsten Element aus dem Array. Deshalb möchte ich, dass die Daten im Hintergrund abgerufen werden und der Benutzer sofort arbeiten kann. (Es ist unmöglich, am 5., 10. oder 1001. Elemente zu springen sofort, es wird genügend Zeit sein, um Daten zu holen, bevor Benutzer auf diesen Seitenzahlen bekommen)

PPS Noch keine richtige Entscheidung :(

+2

Tell, nicht fragen Verwenden eines asynchronen Abschluss Block und stellen die Daten-Array/Neuladen der Tabellen-Ansicht in der Fertigblock – vadian

+0

@vadian Leider wird es „einzufrieren“ Schnittstelle mit.. lange "Fortschrittsbalken" Laden. –

+0

Ihre Benutzeroberfläche sollte nicht von der abgerufenen Data abhängen. Stellen Sie sich vor, dass das Internet c Eine Verbindung ist nicht verfügbar. Ihre Benutzeroberfläche sollte auch in diesem Fall reagieren. Zeige Platzhalter oder leere Daten, bis die echten Daten verfügbar sind. – user3441734

Antwort

0

Sie sollen eine verschachtelte mit Dispatch-Block, etwa so:

func fetch(completion block:(() -> Void)?) { 
    // Run fetch on background thread, to prevent the main thread (and hence your UI) from being 'blocked'. 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), { 

     // 
     // Fetch data... 
     // 

     dispatch_async(dispatch_get_main_queue(), { 
      block?() 
     }) 
    }) 
} 

fetch(completion: { 
    // Update your UI 
}) 
+0

Ja, ich habe darüber nachgedacht, aber wie ich es richtig verstehe, aktualisiert es die Benutzeroberfläche nach jedem Element, angehängt an das Array. Ich habe im Durchschnitt 3000-5000 Elemente im Array. In 1 Sek. Kann es 5-10 Elemente holen, also werde ich 5-10 UI Updates sehen? Tatsächlich repräsentiert jedes Element eine Struktur mit Daten. Ich komponiere die gesamte UI mit Daten von item struct. Der Benutzer kann mit diesen Daten interagieren: Schreiben Sie Text, klicken Sie auf einige Auslöser. Wenn die Benutzeroberfläche aktualisiert wird, kann der Benutzer den Arbeitsprozess verlieren. –

+0

In dieser Situation haben Sie die Wahl: Sie können entweder alle Daten zuerst abrufen (was einige Zeit dauern kann), oder Sie können die Benutzeroberfläche "progressiv" laden. Was ich damit meine, ist, dass Sie 1000 Elemente haben, von denen jedes von den Daten abhängt, die Sie abrufen. Sie sollten eine Ansicht * an ihrem Platz * laden, die "temporär" ist. Wenn die Daten abgerufen wurden, laden Sie die * tatsächliche * Ansicht an ihrer Stelle. Auf diese Weise kann der Benutzer mit UI-Komponenten interagieren, die von Daten abhängen, die bereits abgerufen wurden, während andere Komponenten noch geladen werden. Hoffe das hilft! – Jason

+0

Es scheint der einfachste Weg zu sein, aber aus einigen Gründen kann das Warten zu lange dauern und der Benutzer wird einfach sitzen und in der Fortschrittsbalken sehen. Das ist das Problem, ich will Benutzer sofort mit der Arbeit beginnen –

Verwandte Themen