5

NSUrlConnection次のようにオブジェクトにデリゲートを渡す場合:

[[NSURLConnection alloc] initWithRequest:request delegate:handler];

いつデリゲートでリリースを呼び出す必要がありますか? にあるはずconnectionDidFinishLoadingですか?もしそうなら、私は取得し続けexec_bad_accessます。デリゲートがインストルメントから漏れているのがわかります。

ありがとう

4

5 に答える 5

6

ここにある私のブログ投稿から引用:http: //i.ndigo.com.br/2012/01/releasing-nsurlconnection-and-its-delegate/


デリゲートには特別な考慮事項があるため、デリゲートオブジェクトには特に注意を払う必要がNSURLConnectionあります。これは、常に保持されます。

http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html#//apple_ref/doc/uid/20001697-BAJDDIDG

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:DidFinishLoadingconnection:didFailWithError

于 2011-05-07T19:11:03.350 に答える
3

それは、オブジェクトhandlerが何であるか、およびそれをどのように使用するかによって異なります。たとえば、私は通常self、代理人として次を使用します。

[[NSURLConnection alloc] initWithRequest:request delegate:self];

selfデリゲートは保持されずself、別のオブジェクトによって解放されるため、 release を呼び出す必要はありません。

が新しいオブジェクトである場合handlerは、それを解放する必要があります (オブジェクトを他の目的で使用する必要がない限り、connectionDidFinishLoading: は問題ありhandlerません)。

Cocoa でのメモリ管理のルールに精通していますか?

オブジェクトhandlerとは何か、それをどのように使用しているかをよりよく理解できますか?

于 2009-10-27T18:31:46.580 に答える
-1

オブジェクトハンドラーは、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で報告されているメモリリークを取り除いたようです。

于 2009-10-28T09:02:10.343 に答える