iPhone SDK: Wenn NSData mit NSMutableURLRequest hochgeladen wird, führt dies zu einem mysteriösen Absturz

8

Ich sehe einen Absturz, der 10 oder 20 Sekunden nach einer POST-Anfrage auftritt, die ich gemacht habe ( didReceiveResponse , didReceiveData und connectionDidFinishLoading alle Feuer bevor der Absturz stattfindet).

Dies ist der Code, den ich verwende, um die Anfrage zu stellen:

%Vor%

Was an diesem Absturz sehr merkwürdig ist, ist Folgendes: Wenn ich nicht setHTTPBody mit meinem NSData -Objekt, setValue:@"application/json" für Content-Type und setValue:requestDataLengthString für Content-Length , den Absturz anrufe kommt nicht vor. Ich bin völlig verwirrt, was passiert. Soweit ich das beurteilen kann, steht der Absturz in direktem Zusammenhang mit dem Senden eines NSData Objekts mit meiner Anfrage. Wenn es abstürzt, sind die obersten Elemente im Aufruf-Stack für den Absturz ( EXEC_BAD_ACCESS ) die folgenden:

  • objc_msgSend
  • CFRelease
  • HTTPMessage::~HTTPMessage
  • _CFRelease
  • HTTPWriteFilter::~HTTPWriteFilter

Kann jemand an etwas denken, was ich falsch machen könnte? Ich bin völlig ratlos, was ich falsch mache, wie ich es beheben kann oder wie ich es umgehen kann. Gibt es eine bessere Möglichkeit, POST-Daten zu senden als ich?

    
Rob Ringham 09.03.2009, 23:46
quelle

3 Antworten

7

Sie haben Recht, dass das Problem mit Ihrem NSData -Objekt ist. Sie ordnen es wie folgt zu:

%Vor%

Gemäß den im Programmierungshandbuch für die Speicherverwaltung für Cocoa aufgeführten Regeln, Sie sind kein Eigentümer der Daten, daher sollten Sie später nicht release aufrufen. dataUsingEncoding ruft autorelease auf, so dass das Objekt beim nächsten Löschen des Autorelease-Pools release d ist. Da Sie ein zusätzliches release hinzufügen, versucht der Autorelease-Pool release auf ein Objekt zu setzen, das bereits freigegeben wurde, was den Absturz verursacht.

    
Adam Rosenfield 10.03.2009, 00:05
quelle
5

Sie haben ein automatisch freigegebenes Objekt freigegeben.

Entfernen Sie die Zeile [requestData release]; Du brauchst es nicht. Es verursacht den Absturz, da die Daten von Ihnen freigegeben und dann wieder freigegeben werden, wenn die Daten gesendet werden, was eine zu viele Freigaben ist.

Im Allgemeinen rufen Sie die Freigabe für ein Objekt nicht auf, es sei denn, Sie weisen es zu, oder die Dokumentation sagt explizit, dass das zurückgegebene Objekt nicht automatisch freigegeben wurde. (was selten ist).

Mit diesem Code brauchen Sie sich keine Sorgen zu machen, dass Sie ein automatisch freigegebenes Objekt verwenden, so weit der Speicher reicht, egal was Sie tun, der Speicher bleibt so lange, bis das zugrunde liegende Framework die Daten entlang der Leitung sendet.

Ich weiß nicht, ob es eine bessere Möglichkeit gibt, Daten zu posten - der Code, den Sie haben, sieht gut aus, abgesehen davon, dass die json-Daten wahrscheinlich sowohl in einer Zeichenkette als auch in einem Datenobjekt dupliziert werden, aber die Menge der gesendeten Daten kann klein sein. Wenn dies nicht der Fall ist, sollten Sie die jsonData-Zeichenfolge sofort freigeben, nachdem Sie die Daten erstellt haben. (Das würde bedeuten, dass die jsonData-Zeichenfolge zusammen mit den Daten aus einem alloc / init-Aufruf stammen müsste). Oder machen Sie das jsonData nicht als String, sondern machen Sie es gleich von Anfang an als nützliche Daten, aber das ist vielleicht peinlich.

- Tom

    
Tom Andersen 10.03.2009 00:02
quelle
1

Überprüfen Sie auch den Aufruf von [urlString release]; . Wenn urlString mit etwas wie stringWithFormat oder stringwithString erstellt wurde, sollten Sie es nicht freigeben.

    
Roger Nolan 10.03.2009 06:57
quelle

Tags und Links