2012-03-31 13 views
4

Ich habe eine lange laufende Aufgabe, die ich abgeschlossen werden soll, auch wenn die Anwendung in den Hintergrund geschoben wird. siehe Aus der Dokumentation kann ich, dass die Art und Weise, dies zu tun ist, um die beginBackgroundTaskWithExpirationHandler zu verwenden: Funktion und asynchron eine Aufgabe starten ausgeführt, wie im folgenden Code-Schnipsel:iOS: Wann wird der Hintergrund-Task-Code-Block aufgerufen?

UIApplication* application = [UIApplicationsharedApplication]; 
bgTask = [application beginBackgroundTaskWithExpirationHandler:^{ 
    // Clean up any unfinished task business by marking where you. 
    // stopped or ending the task outright. 

    [application endBackgroundTask: bgTask]; 
    bgTask = UIBackgroundTaskInvalid; 
}]; 

// Start the long-running task and return immediately. 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 

    // Do the work associated with the task, preferably in chunks. 
     for (int i = 0; i < 3; i++){ 

     [self doChunkOfWork]; 
    } 

    // end work 
    [application endBackgroundTask:bgTask]; 
    bgTask = UIBackgroundTaskInvalid; 
}); 

Jetzt verstehe ich, dass der zweite Codeblock asynchron ausgeführt wird und wenn die Anwendung fertig ist, wird sie benachrichtigt, und die Aufgabe wird als ungültig markiert. Kann mir jedoch jemand mitteilen, unter welchen Umständen der erste Codeblock ausgeführt wird und wie die ersten und zweiten Blöcke verknüpft werden? Ist es einfach so, dass, weil ich eine Aufgabe gestartet habe und sequentiell das nächste, was ich tue, dispatch_async heißt, dass die beiden Blöcke verknüpft werden?

Antwort

5

Diese Blöcke haben keine "magische" Beziehung.

Der zweite Block wird in die Warteschlange gestellt und asynchron ausgeführt, wie Sie angeben. Der erste Block wird only ever be called by the system wenn:

  1. Die Anwendung wird in den Hintergrund gesendet (dh die Benutzer wechselt zu einer anderen App)
  2. Ihren zweiten Blockes des [self doChunkOfWork] Blöcke länger als etwa 10 Minuten (auf aktuellen iOS-Versionen) .

Wenn -doChunkOfWork Blöcke wird [application endBackgroundTask:bgTask] nie genannt werden, und das System wird mit Recht! -Denken Sie immer noch Arbeit zu tun. iOS legt ein Limit für die Zeit fest, die Sie im Hintergrund arbeiten können, und ruft Ihren Verfalls-Handler (der erste Block) auf, wenn Sie dieses Limit überschreiten.

Ihre aktuelle Implementierung für den Ablaufbehandlungsroutine markiert die Aufgabe sofort als abgeschlossen. An diesem Punkt würde Ihre Anwendung nicht mehr ausgeführt werden, und wenn doChunkOfWork noch läuft, wird es angehalten. (Tatsächlich werden alle Threads der Anwendung pausiert.)

Zu einem späteren Zeitpunkt kann der Benutzer wieder zu Ihrer App wechseln. Ihre Threads werden dann fortgesetzt und doChunkOfWork wird weiter ausgeführt, wo es war.

+2

Es ist erwähnenswert, dass, wenn all das oben genannte '' doChunkOfWork' 'noch läuft, das nächste Mal, wenn Ihre App im Hintergrund läuft, das System Ihnen keine zusätzliche Zeit gibt, weil Ihr Verfallshandler die Aufgabe bereits als erledigt markiert hat. Dies ist wahrscheinlich nicht das, was Sie wollen. –

+0

Richtig! Aber wie schlagen Sie vor, dieses Problem zu lösen? – Dev

+1

Kehren Sie die Aufgabe tatsächlich ab, wenn Sie vom Exspiration-Handler dazu aufgefordert werden. Wenn Sie eine 'NSOperation' verwenden, sollten Sie sie in [response to cancel] ändern (http://developer.apple.com/library/ios/documentation/Cocoa/Reference/NSOperation_class/Reference/Reference.html#//apple_ref/doc/uid/TP40004591-RH2-SW18) und rufen Sie 'cancel' von Ihrem Exspiration-Handler auf. Wenn Sie etwas tun, das in Ihrem Handler nicht blockierend ist, setzen Sie ein Flag, damit es abgebrochen wird und später mit einem neuen Aufruf von 'beginBackgroundTaskWithExpirationHandler:' neu gestartet wird. –

Verwandte Themen