NSUrlConnection
次のようにオブジェクトにデリゲートを渡す場合:
[[NSURLConnection alloc] initWithRequest:request delegate:handler];
いつデリゲートでリリースを呼び出す必要がありますか? にあるはずconnectionDidFinishLoading
ですか?もしそうなら、私は取得し続けexec_bad_access
ます。デリゲートがインストルメントから漏れているのがわかります。
ありがとう
NSUrlConnection
次のようにオブジェクトにデリゲートを渡す場合:
[[NSURLConnection alloc] initWithRequest:request delegate:handler];
いつデリゲートでリリースを呼び出す必要がありますか? にあるはずconnectionDidFinishLoading
ですか?もしそうなら、私は取得し続けexec_bad_access
ます。デリゲートがインストルメントから漏れているのがわかります。
ありがとう
ここにある私のブログ投稿から引用:http: //i.ndigo.com.br/2012/01/releasing-nsurlconnection-and-its-delegate/
デリゲートには特別な考慮事項があるため、デリゲートオブジェクトには特に注意を払う必要がNSURLConnection
あります。これは、常に保持されます。
initWithRequest:delegate:
特別な考慮事項:接続はデリゲートを保持します。接続の読み込みが完了するか、失敗するか、キャンセルされると、デリゲートが解放されます。
したがって、それを考慮して、代理人が正しく解放されるようにするためのいくつかのオプションがあります。2つの簡単なオプションについて説明します。
最初の、そして最も一般的に使用されるのは、NSURLConnectionをデリゲートとして初期化するのと同じクラスを使用することです。
[[NSURLConnection alloc] initWithRequest:request self];
そうすることで、クラスの保持カウントは、接続の開始時に1増加し、接続の読み込みが完了するか、失敗するか、キャンセルされた後に1減少するため、メモリリークは発生しません。
2番目のオプション、つまり実行しようとしているオプションは、別のオブジェクトを使用してすべての接続呼び出しを処理することです。これも問題なく機能しますが、メモリに関して特別な注意が必要になります。問題を解決するためにできる簡単なことの1つは、自動解放オブジェクトを使用して接続を初期化することです。
//creates the handler object
MyHandlerClass *handler = [[MyHandlerClass alloc] init];
//creates the connection with handler as an autorelease object
[[NSURLConnection alloc] initWithRequest:request delegate:[handler autorelease]];
または、接続を作成した直後にハンドラーを解放することもできます(接続によって既に保持されているため)
//creates the handler object
MyHandlerClass *handler = [[MyHandlerClass alloc] init];
//creates the connection with handler
[[NSURLConnection alloc] initWithRequest:request delegate:handler];
//releases handler object
[handler release];
どちらの方法でも、ハンドラーオブジェクトの所有権は接続クラスにのみ残されます。これにより、ハンドラーオブジェクトは、読み込みが完了するか、失敗するか、キャンセルされた直後に解放され、メモリリークは発生しません。
編集:上記のオプションのいずれかを実行することにより、メソッドでデリゲートを解放することを心配する必要はありません(ただし、接続を解放する必要がありますconnection:DidFinishLoading
)connection:didFailWithError
。
それは、オブジェクトhandler
が何であるか、およびそれをどのように使用するかによって異なります。たとえば、私は通常self
、代理人として次を使用します。
[[NSURLConnection alloc] initWithRequest:request delegate:self];
self
デリゲートは保持されずself
、別のオブジェクトによって解放されるため、 release を呼び出す必要はありません。
が新しいオブジェクトである場合handler
は、それを解放する必要があります (オブジェクトを他の目的で使用する必要がない限り、connectionDidFinishLoading: は問題ありhandler
ません)。
Cocoa でのメモリ管理のルールに精通していますか?
オブジェクトhandler
とは何か、それをどのように使用しているかをよりよく理解できますか?
オブジェクトハンドラーは、connectionDidFinishLoading didReceiveDataなどを実装するために使用されます。私は多くのWebサービスを呼び出し、それぞれに1つのオブジェクトを作成する代わりに、それらすべての中央クラスを持っています。
@interface DataService : NSObject {}
- (void) search:(NSString *) name byAddress:(NSString *)address;
@end
したがって、そのメソッドを実装すると、渡すデリゲートが作成されます。
SearchDelegate *delegate = [[SearchDelegate alloc] init];
[self sendRequestToUrl:urlString withJson:jsonString andHandler:delegate];
Instrumentsで見ているのは、SearchDelegateでメモリリークが発生していることです...したがって、実際には保持されていると思います。
少しいじくり回して、sendRequestToUrlMethodを次のように変更しました。
// http code setup blah...
[[NSURLConnection alloc] initWithRequest:request delegate:handler];
[handler release];
これは、Instrumentsで報告されているメモリリークを取り除いたようです。