2012-04-11 3 views
12

Hier tauchte ist ist das Szenario:offene Asynchron Webanfragen Umgang mit, wenn UIViewController (AFNetworking)

-A UIViewController (A) auf den Navigationsstapel
-Auf viewDidLoad ein Asynchron-GET AFNetworking genannt wird gedrückt wird (a Singleton AFHTTPClient in der gesamten Anwendung geteilt), um verschiedene Benutzerelemente in der Ansicht zu füllen (sagen wir ein UILabel).
-Der Benutzer drückt die Zurück-Taste, bevor die Anforderung
-Assume andere aktive Ansicht gibt Controller-Anfragen machen können, so dass Sie nicht alle offenen Operationen abbrechen

So 1 Frage # ist, sollten Sie die offenen Anfragen verfolgen von UIViewController A gemacht und die ausstehenden löschen, wenn der Benutzer diese Ansicht verlässt, oder sollten Sie sie beenden und ignorieren sie? Da AFNetworking Blöcke verwendet, bleiben die aktualisierten Benutzerelemente im Block erhalten und verursachen daher keinen Absturz, wenn der Erfolg/Fehler-Block nach dem Aufrufen der Ansicht ausgeführt wird. Der Nachteil, sie zu ignorieren, scheint jedoch ein unnötiger Netzwerkverkehr zu sein.

Frage 2 ist, wo würden Sie den Code ausführen, um die von UIViewController A durchgeführten Operationen abzubrechen? viewDidDisappear scheint nicht richtig zu sein, weil der Benutzer möglicherweise vorwärts gegangen ist (eine neue Ansicht auf den Stapel geschoben hat) statt zurück (die aktuelle Ansicht). In diesem Fall möchten Sie die offenen Anfragen nicht abbrechen, weil der Benutzer kommen könnte zurück zur aktuellen Ansicht und es wird nicht erneut geladen. Ich glaube jedoch nicht, dass dealloc oder viewDidUnload aufgerufen wird, während die Anfrage ausgeführt wird, da der Block die Benutzerelemente beibehalten wird, so dass ich nicht glaube, dass er dorthin gehen kann.

Würde mich über diese Gedanken freuen. Was halten Sie für eine gute Praxis?

+1

Randbemerkung: viewDidUnload hat nichts mit der Retain-Anzahl seines View-Controllers zu tun. Es wird aufgerufen, wenn der Ansichtscontroller seine Ansicht loswerden möchte (und möglicherweise später erneut lädt). Dies passiert beispielsweise bei Offscreen-View-Controllern in einer Registerkarte oder einem Navigations-Controller, wenn Sie eine Speicherwarnung erhalten. So kann es während Ihrer Anfragen aufgerufen werden. – rickster

Antwort

7

Im Allgemeinen müssen Sie Anfragen nicht wirklich abbrechen, wenn ein Benutzer einen View-Controller verlässt. In Bezug auf die Speicherverwaltung verhindert ein Verweis auf block self alle Abstürze, die durch das Senden von Nachrichten an freigegebene Instanzen verursacht werden, also keine Sorgen.

Soweit Benutzererfahrung, würde ich sagen, dass Sie sich nicht wirklich darum kümmern sollten, bis es ein Problem ist (wir Entwickler haben ein Talent für völlig falsch zu schätzen, was in unseren Anwendungen langsam ist). Wenn Sie jedoch große GET-Anfragen machen und es bemerkenswerte Trägheit erzeugt, wäre mein Vorschlag, den Controller HTTPClient -cancelAllHTTPOperationsWithMethod:path: in -viewDidUnload: zu machen (jeder andere Rückruf wäre zu früh).

+1

Warum Anfrage in 'viewDidUnload:' abbrechen? Ich denke, die Anfrage sollte sofort nach dem Aufruf des View-Controllers abgebrochen werden. Ein besserer Ansatz wäre es zu überprüfen, ob sich der View-Controller noch in 'viewDidDisappear:' im Stack befindet. Wenn nicht, die Anfrage abbrechen. Sie können dies mit 'if (! [Self.navigationController.viewControllers containsObject: self]] überprüfen. {NSLog (@ "Abbruch der Anfrage"); } ' – nonamelive

+0

Sie überdenken es. Es kann Situationen geben, in denen das Abbrechen sofort sinnvoller ist, aber da es nicht ungewöhnlich ist, dass Benutzer sofort nach dem Öffnen einer Ansicht drücken, zahlt es sich wahrscheinlich nicht aus, übermäßig proaktiv zu sein. – mattt

0

Vielleicht könnten Sie einen Singleton haben, der alle Netzwerk-Sachen verwaltet, und setzen Sie seinen Vertreter auf die aktuelle VC (in ViewDidLoad), so dass Sie alle eingehenden Daten erhalten, und senden Sie eine Nachricht abbrechen, wenn die VC verschwindet (oder sonst lass einen anderen vc zu seinem Delegierten werden). Oder der Singleton könnte die Daten für irgendeinen späteren Zugriff durch irgendeinen VC behalten. Aus diesem Grund tendiere ich dazu, keinen asynchronen Code in meine VCs zu legen.

+0

Ich weiß, wie Sie verfolgen, welche Anfragen abzubrechen sind, die Frage ist mehr, sollten Sie sie abbrechen, und wenn ja, auf welchem ​​Ereignis sollten Sie sie abbrechen (da viewDidUnload und dealloc nicht aufgerufen werden, bevor die Anfrage abgeschlossen ist). – Joel

+0

@Joel Sie können überprüfen, ob der View-Controller in 'viewDidDisappear:' angezeigt wird. Bitte sehen Sie den Kommentar, den ich in Mattts Antwort hinterlassen habe. – nonamelive

+1

Danke.Ich habe auch nach dieser Frage gelernt, dass Sie Pop in ViewDidDisapper überprüfen können, indem Sie dies tun: if ([self isMovingFromParentViewController] || [Selbst IsBeingDismissioned]) – Joel