2011-02-06 10 views
0

Apple guideは、接続オブジェクトを解放することに関して非常に具体的です。didFailWithErrorconnectionDidFinishLoadingで行われます。しかしNSURLConnectionを使用した非同期要求:解放するとき

、私は同じことを行うとき、私は後でそれはそう

*** -[NSURLConnection releaseDelegate]: message sent to deallocated instance 0x1001045b0 

ゾンビモードでこれを取得し、私のための接続を解放するのAppKitでのいくつかのコードがあります。

私はアップルのガイドが間違っていると思いますが、恐ろしいメモリリークを取得したり、古いOSXバージョンなどの微妙な非互換性を導入したくないと思います。

この場合、ドキュメントを無視しても安全ですか?

編集
コードあなたが

[NSURLConnection connectionWithRequest:request delegate:delegate]; 

との接続を作成しましたので、あなたが「ドン要求

URLConnectionDelegate *delegate = [[URLConnectionDelegate alloc] initWithSuccessHandler:^(NSData *response) { 
     ... 
    }]; 
    [NSURLConnection connectionWithRequest:request delegate:delegate]; 

    // I do not release delegate when testing for this issue, not sure whether I should in general 

Delegateクラス自体

- (void)connectionDidFinishLoading:(NSURLConnection *)connection { 
    successHandler(receivedData); 

    [receivedData release]; 
    Block_release(successHandler); 

    // do we really need this???????? 
    [connection release]; 
} 
+0

docsから: 'NSURLConnection'は、デリゲートを初期化するときにそのデリゲートを保持します。接続が完了すると、デリゲートを解放します。失敗するか、キャンセルされます。デリゲートを過剰にリリースしたようです。 –

+0

@Bavariousここではデリゲートを公開しません。 (私が別の質問であるべきかどうか) '[connection release];を追加するとエラーが表示され、削除すると消えます。 –

+0

@Bavariousまた、エラー文法は、リリースされた 'NSURLConnection'インスタンスでメソッド' releaseDelegate'が呼び出されたことを示唆しています。代理人ではありません。 –

答えて

3

を作成します接続オブジェクトを所有しているので、解放しないでください。

言われているように、私はそれをお勧めしません。オブジェクトを所有していない場合、自動解放プールの排水サイクルよりも寿命が長くなるという保証はありません。つまり、接続オブジェクトがロード完了前に(自動)解放されている可能性があります。代わりに、接続を保持するために保持して宣言されたプロパティを作成します。

@property (retain) NSURLConnection *connection; 

が宣言されたプロパティに、あなたの接続オブジェクトを割り当てる:

self.connection = [NSURLConnection connectionWithRequest:request 
    delegate:delegate]; 

と、接続の読み込みが完了または失敗したとき、nilを割り当てることによって、それを解放します宣言されたプロパティに:それは唯一の接続がロードされている間に存在する必要がある場合

self.connection = nil; 

デリゲートについては、あなたはそれがSINC自動解放することができます接続がデリゲートを保持する:

URLConnectionDelegate *delegate = [[[URLConnectionDelegate alloc] 
    initWithSuccessHandler:^(NSData *response) { 
    // … 
}] autorelease]; 

self.connection = [NSURLConnection connectionWithRequest:request 
    delegate:delegate]; 
+0

ありがとう、私はそれがより明確に表示されます。しかし 'alloc'を使ってコレクションを作成する方が簡単ではないでしょうか?私はループでいくつかを作成し、辞書やセットを使用しなければならないだろうが、 'NSDictionary'を発行し、他の人がキーをクローンすると手間がかかります。だから、あなたは 'alloc'と' release'の解決策が有効だと思いますか? –

+0

@NikitaRybakあなたは 'alloc'を使ってそれらを作成し、宣言されたプロパティやその他の所有権メカニズムを保持するためにそれらを割り当てたり、アプリケーションアーキテクチャに適していれば終了/失敗時に解放することはできません。私は、通常、接続の参照を保持することをお勧めします。これは、ダウンロードが完了した接続や失敗した接続に関係なく、キャンセル(および解放)することができるためです。辞書を使用する場合(キーをコピーする必要がある)は、代わりに(オブジェクトを保持する)配列を使用するか、コピーできるオブジェクト(文字列など)に接続をマッピングする単純なクラスを使用できます。 –

+0

この投稿は本当ですか?あなたが本質的なアクティビティーを開始する場合には、それ自体を保持し、それを自分で保持する必要はありません。 NSURLConnectionは、接続が終了するかエラーが発生するまで保持されます。同様の例はUIAlertViewです。あなたがそれを見せた後に表示された後でも、それを保持しておく必要はありません。ユーザーがそれを却下するまで、それ自体は保持されます。 – David

関連する問題