2009-03-09 5 views
8

POST要求が完了してから10秒または20秒後にクラッシュが発生しました(クラッシュが発生する前にdidReceiveResponsedidReceiveDataおよびconnectionDidFinishLoadingがすべて発砲しています)。iPhone SDK:NSMutableURLRequestを使用してNSDataをPOSTすると、不思議なクラッシュが発生する

これは私が要求をするために使用しているコードです:

NSURL* url = [[NSURL alloc] initWithString:urlString]; 
[urlString release]; 

NSData* requestData = [jsonData dataUsingEncoding:NSUTF8StringEncoding]; 
NSString* requestDataLengthString = [[NSString alloc] initWithFormat:@"%d", [requestData length]]; 

NSMutableURLRequest* request = [[NSMutableURLRequest alloc] initWithURL:url]; 
[request setHTTPMethod:@"POST"]; 
[request setHTTPBody:requestData]; 
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; 
[request setValue:requestDataLengthString forHTTPHeaderField:@"Content-Length"]; 
[request setTimeoutInterval:30.0]; 
[url release]; 
[requestData release]; 
[requestDataLengthString release]; 

m_URLConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; 
[request release]; 

このクラッシュは非常に奇妙です:NSDataオブジェクトで setHTTPBodyを呼び出さない場合、Content-TypeContent-LengthsetValue:requestDataLengthStringでは、がクラッシュしてもは発生しません。私は何が起こっているかについて完全に困惑しています。私が知る限り、クラッシュは私の要求と共にNSDataオブジェクトを送信することに直接関連しています。クラッシュすると、クラッシュ(EXEC_BAD_ACCESS)の呼び出しスタックの先頭の要素は次のようになります。

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

誰かが私が間違っているかもしれない何かを考えることができますか?私は何が間違っているのか、それをどうやって解決するのか、それを回避する方法については全く失われています。私がやっているやり方よりもデータをPOSTする良い方法はありますか?

+0

試してみてください:[requestData release]行を削除するとクラッシュしますか? – squelart

答えて

7

問題があなたのNSDataオブジェクトであるという点で、あなたは正しいです。あなたはそのようにそれを割り当てている:

NSData* requestData = [jsonData dataUsingEncoding:NSUTF8StringEncoding]; 

Memory Management Programming Guide for Cocoaにレイアウトルールによると、あなたは、データの所有者でないなら、あなたは後でそれにreleaseを呼び出すべきではありません。 dataUsingEncodingautoreleaseを呼び出すので、オブジェクトは次に自動解放プールが廃棄されるときにreleaseになります。 releaseを追加しているため、自動解放プールでは、すでに割り当てが解除されているクラッシュの原因となっているオブジェクトがreleaseになる可能性があります。

+0

それはまさにそれでした。ありがとうございました! –

5

自動リリースされたオブジェクトをリリースしました。

[requestData release]行を削除します。 あなたはそれを必要としません。データがあなたから解放されてからデータが送信されたときに再びリリースされるため、クラッシュが発生します。これはリリースが多すぎます。

一般に、割り当てられない限り、オブジェクトに対してreleaseを呼び出さないでください。または、ドキュメントでは、返されたオブジェクトがオートリリースされていないことが明示的に示されます。 (これはまれです)。

このコードでは、オートレリースされたオブジェクトを使用していることを心配する必要はありません。メモリに関係なく、メモリは、基本フレームワークがワイヤに沿ってデータを送信するまで。

データを投稿するより良い方法があるかどうかわかりません.Jsonデータ以外のコードは文字列とデータオブジェクトの両方に重複している可能性がありますが、送信は小さいかもしれません。そうでない場合は、データを作成した直後にjsonData文字列を明示的に解放する必要があります。 (これは、jsonData文字列wuldがalloc/init呼び出しのデータである必要があることを意味します)。または、jsonDataを文字列として作成しないで、最初からnsmutableデータとして作成してください。ただし、それは扱いにくいかもしれません。

--Tom

+0

くそーオートレリーズ:-)私はこのミスを最後にしたと思います。ありがとうございました! –

1

[urlString release];への呼び出しもチェックしてください。 urlStringstringWithFormatstringwithStringなどで作成されている場合は、リリースしないでください。

関連する問題