2009-04-06 5 views
2

Ich habe ein paar Tabs in meiner iPhone-Anwendung, die ein paar Sekunden dauern, um zu laden (ziehen große Mengen von Daten aus einer lokalen SQLite-Datenbank). Wenn die Benutzer die Registerkarten berühren, scheint es, als würde die Anwendung nichts tun. Ich habe versucht, ein Fenster mit einem Spinner aufzustellen, es wird jedoch nie angezeigt, da die Verarbeitung unmittelbar folgt.NSRunloops und Erzwingen Ereignisverarbeitung

Ich weiß, ich habe ein paar verschiedene Optionen zum asynchronen Laden der Daten, aber ich wollte die Community abfragen und sehen, ob es potenzielle Probleme mit nur zwingt einen anderen Zyklus des NSRunloop, um das Fenster zu zeigen.

Hier ist, was mein Code sieht aus wie ...

[[ActivityIndicator sharedActivityIndicator] show]; 
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate date]]; 

Auf einer Skala von 1 bis 10, wie schlecht würden Sie dies Hack bewerten?

Antwort

3

Ich weiß nicht, wo ich es bewerten würde, aber ich weiß, ich würde es nicht so machen wollen. Es scheint nur eine schlechte Idee zu sein, mit dem Standard-Runloop des Systems zu spielen.

Es gibt ein paar, was ich denke, sind gute Ansätze. Am einfachsten ist die zusätzliche Verarbeitung in einer separaten privaten Methode zu setzen, und dies dann tun:

[[ActivityIndicator sharedActivityIndicator] show]; 
[self performSelector:@selector(processingMethod) withObject:nil afterDelay:0]; 

Das processingMethod verursacht am Ende der Laufschleife aufgerufen werden, nachdem Ihre Anzeige angezeigt wird. Sollte gut funktionieren.

Der eine Vorbehalt ist, dass, wenn Ihr Indikator animiert ist, abhängig davon, wie es eingerichtet ist, es möglicherweise nicht animiert werden, während ProcessingMethod ausgeführt wird. In diesem Fall würden Sie processingMethod in einem Hintergrund-Thread ausgeführt werden, die ein wenig komplizierter sein könnte, oder könnte genauso tun dies so einfach sein statt:

[self performSelectorInBackground:@selector(processingMethod) withObject:nil]; 

Die mögliche Komplikation, dass es am Ende processingMethod, wenn Sie die Ergebnisse Ihrer Verarbeitung anzeigen möchten, müssen Sie möglicherweise eine Methode zurück auf den Haupt-Thread aufrufen.

+0

ich mit Jack einverstanden und ich denke, dass Lounges ist für seine zweite Antwort „performSelectorInBackground“ suchen - mit Rückruf. – mobibob

1

Meine Erfahrung ist, dass der Ereignisbehandlungscode auf dem iPhone nicht reentrant ist. Wenn Sie den Runloop im Standardmodus ausführen, sollten Sie auf verschiedene Abstürze vorbereitet sein. Ich habe festgestellt, andere haben Frage zu:

  1. http://lists.apple.com/archives/xcode-users/2009/Apr/msg00313.html
  2. http://www.iphonedevsdk.com/forum/iphone-sdk-development-advanced-discussion/16246-trying-make-modal-dialog-using-nested-nsrunloop.html
+0

Sie sind richtig, und weiterhin, Apples Dokument besagt, dass der Thread nicht wiedereintrittsfähig ist. Sie sollten nicht auf Daten anderer Threads zugreifen. Der Rückruf - und "geben Sie die Daten" - ist der bevorzugte Ansatz. – mobibob

+0

Was meinst du mit Wiedereintritt? – airpaulg