Multithreading in iOS - wie zu zwingen, einen thread zu warten, für eine Bedingung?
Ich bin erstellen einer Anwendung, die holt sich die Ergebnisse aus einer Datenbank, ich nutze MBProgressHUD zu zeigen, den Fortschritt der Abfrage mit einer animation. Die Methode, die ich verwenden, ruft die animation während der Ausführung einer Methode in einem anderen thread und sobald es fertig ist, verbirgt die animation. Meine Frage ist, nach dem Aufruf:
[HUD showWhileExecuting:@selector(getResults) onTarget:self withObject:nil animated:YES];
Ich würde gerne, wenn es keine Ergebnisse, anzeigen einer Warnung, die besagt das, und wenn es gibt, laden Sie die nächste Ansicht. Bisher habe ich diesen code:
[HUD showWhileExecuting:@selector(getResults) onTarget:self withObject:nil animated:YES];
if(self.thereAreEvents) {
[self performSegueWithIdentifier:@"searchResults" sender:self];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"No results" message:@"Sorry, there are no results for your search. Please try again." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
self.thereAreEvents
festgelegt wird, am Ende der getResults
Methode. Jedoch, da diese Methode aufgerufen wird, in einem anderen thread wird diese Linie die Ausführung fortgesetzt und zeigt die Warnung, auch wenn es Ereignisse in der Datenbank.
Also, von hier aus habe ich zwei Fragen: Was ist der einfachste Weg zur Implementierung einer warte-signal-Mechanismus in iOS und was ist der effizienteste Weg zur Umsetzung dieser Art von Mechanismus in iOS?
Dank!
InformationsquelleAutor KerrM | 2012-03-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie auch eine
NSConditionLock
.So, es wäre so etwas wie dieses auf thread 1:
Und in der Schwebepalette:
Obwohl eine viel bessere Lösung wäre, pass block oder ein Ziel/selector an der HUD, die es ausführen, wenn die Ergebnisse abgerufen werden.
EDIT: also würden Sie am Ende mit code wie:
Und in der Schwebepalette:
Mit HUD mit der zusätzliche Intelligenz, die eine
dispatch_block_t
als letztes argument und nennen es, wenn Ergebnisse vorliegen (ob die Gewährleistung Versand zurück an den main-thread oder etwas anderes).Die 'pass-a-block' - Muster ist relativ neu, aber scheint zu sein, die Richtung von Apple sind unter der Leitung des pro-die neuen APIs in iOS 5. Check-out z.B.
TWRequest
oderACAccountStore
. In der Tat, es würde wohl besser sein, aufcompletionHandler:
eher alsperformWhenFinished:
zur Versorgung der block, wie in der convention, scheint zu entstehen.InformationsquelleAutor Tommy
Können Sie mit einem busy-wait-Schleife für eine quick-and-dirty-Lösung:
In "echten" code-es ist besser ein semaphore:
Dies ist besser als das busy-loop, weil der blockierte thread nicht fressen CPU-Zeit.
Die beste Lösung ist zu halten von der Sperrung und Umgestaltung Ihres Codes zu arbeiten asynchron. In Ihrem Fall sollten Sie die Anzeige ein spinner und starten Sie das herunterladen von Daten entstehen. Bei den Daten ist das herunterladen abgeschlossen ist, erhalten Sie eine asynchrone callback (entweder durch einen block oder eine target/action callback) und die Ergebnisse anzuzeigen, oder zeigen die Fehler-alert. Die Blockierung mit einem busy-loop oder eine semaphore ist ein armer Mann, der die Lösung in diesem Fall.
Nur ein Kommentar, dispatch_release ist nicht erforderlich, da iOS6
InformationsquelleAutor zoul
Nicht sicher, ob dies der beste Weg, es zu tun, aber ich würde versuchen mithilfe einer while-Schleife zu beobachten, einige boolean mit so etwas wie [NSThread sleepForTimeInterval:1]; innerhalb der Schleife.
Vielleicht legen Sie ein timeout als gut.
InformationsquelleAutor Jiho Kang
Dies ist dein Weg:
Concurrency Programming Guide
Auch: Synchronisation
Mehr scharf: Mithilfe Von Sperren. Ich denke, das Letzte geben konnte, die am besten helfen.
Weiterer einfacher Ansatz, es ist schlimm, aber funktioniert
InformationsquelleAutor SVGreg
können Sie dispatch_time_t..
InformationsquelleAutor Hardik Darji