2012-05-10 8 views
5

Ich habe UITableView mit etwas Inhalt, der in asynchron Weise geladen wird. Wenn der Benutzer das Gerät dreht, muss ich [tableView reloadData] in -willRotateToInterfaceOrientation Methode machen. ReloadData funktioniert in meinem Fall asynchron.Wie kann MainThread warten, bis eine asynchrone Aktion ausgeführt wird?

Ich verstehe, dass reloadData funktioniert im Haupt-Thread, aber es feuert CellForRowAtIndexPath, die in meinem Fall async funktioniert.

Also die Frage ist, wie man Main Thread warten bis UITableView's reloadData endet.

Antwort

2

Wenn Sie reloadData von willRotateToInterfaceOrientation aufrufen, wird es im Hauptthread aufgerufen. Tatsächlich sind UIViews NICHT Thread-sicher und sollten immer nur vom Haupt-Thread behandelt werden (falls aus irgendeinem Grund jemand die Idee bekommt, reloadData von einem anderen Thread aufzurufen).

Ich denke, es gibt Verwirrung in Bezug auf "asynchron" als Begriff. Asynchrone Callbacks für UI-Delegaten wie "willRotateToInterfaceOrientation" werden im Hauptthread aufgerufen. Asynchron zu sein, bedeutet nicht unbedingt einen anderen Thread (obwohl asynchron "parallel" ausgeführt wird).

Ich würde empfehlen, auf der Apple-Dokumentation für NSRunLoop nachzulesen. Es ist ein wesentlicher Bestandteil der Art und Weise, wie iOS-Apps ausgeführt werden und ist ein Muss für App-Programmierer, um es zu verstehen. bis UITableView Daten neu geladen wird

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html

+0

Ich verstehe, dass reloadData im Haupt-Thread aufgerufen wird. Aber realodData ruft cellForRowAtIndexPath auf ... und diese Methode muss einige Daten asynchron laden. –

+0

Ich sehe, so dass Sie nicht warten, dass reloadData abgeschlossen wird, sondern die asynchronen Aufgaben, die reloadData zum Abschluss abfeuert. Könnten Sie Ihre Frage entsprechend abändern? NSRunLoop ist immer noch was du willst, obwohl ich nicht verstehe, warum du deine Hauptthread-Geisel halten willst, während asynchrone Daten geladen werden. – NSProgrammer

+0

Ein Haupt-Thread muss auf reloadData warten, da dies die Rotationsanimation angenehm macht. –

3

können Sie CFRunLoopRun benutzen, um Ihre Haupt-Thread warten zu machen. Nachdem die Daten neu geladen wurden, rufen Sie CFRunLoopStop auf und übergeben das Ergebnis CFRunLoopGetMain als Parameter.

+0

Danke, ich sehe das nicht so einfach, die Dokumentation zu lesen. Ich werde versuchen zu verstehen. –

2

Sie müssen die Daten Ihrer Tabelle im Hintergrund laden und dann die reloadData-Methode von UITableView aufrufen.

Sie können GCD verwenden, um Ihre Ladefunktion problemlos asynchron an eine Hintergrundwarteschlange zu senden. Wenn diese Aufgabe abgeschlossen ist, muss der Arbeitsthread einen Block an den Hauptthread zurücksenden, der [tableView reloadData] aufruft. Hier ist wie:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{ 

    ... 
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
    dispatch_async(queue, ^{ 

    // load your table data here 
    [self loadMyTableData]; 

    // when done dispatch back to the main queue to load the table 
    dispatch_queue_t mainQueue = dispatch_get_main_queue(); 
    dispatch_async(mainQueue, ^{ 

     [self.tableView reloadData]; 
     }); 
    }); 
    ... 
} 
+0

So machen Sie [self loadMyTableData]; Ich muss die Hälfte des Codes ändern, um die Daten zu speichern und dann an meine untergeordneten uitableviewcells und ihren Inhalt zu übertragen –

Verwandte Themen