9

http からデータを取得する nsurl を設定しました。インストゥルメントを実行すると、NSFNetwork オブジェクトがリークしていると表示されます。

(void)ButtonClicked でtheConnectionを解放するにはどうすればよいですか? それとも後でリリースされますか?

- (void)ButtonClicked {
    NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:KmlUrl]
                                                cachePolicy:NSURLRequestUseProtocolCachePolicy
                                            timeoutInterval:20.0f];

    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
    if (theConnection) {
        // receivedData is declared as a method instance elsewhere
        NSMutableData *receivedData = [[NSMutableData data] retain];
        [self setKMLdata:receivedData];
    } else {
        // inform the user that the download could not be made
    }
}


- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    // append the new data to the receivedData
    // receivedData is declared as a method instance elsewhere
    [KMLdata appendData:data];
    NSLog(@"didReceiveData");
}


- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    // release the connection, and the data object
    [connection release];
    [KMLdata release];
}


- (void)connection:(NSURLConnection *)connection  didFailWithError:(NSError *)error
{
    // release the connection, and the data object
    [connection release];
    // receivedData is declared as a method instance elsewhere
    [KMLdata release];

}
4

4 に答える 4

17

私はついにこれに対する答えを見つけました。

上記のコード ( SDK docsのほぼ正確なサンプル) のエラーは、メモリ管理コードにはありません。自動リリースは 1 つのオプションであり、手動リリースは別のオプションです。NSURLConnection オブジェクトの処理方法に関係なく、NSURLConnection を使用するとリークが発生します。

まず、ここに解決策があります。これらの 3 行のコードを、connectionDidFinishLoading、didFailWithError、および NSURLConnection オブジェクトを解放するその他の場所に直接コピーするだけです。

NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
[sharedCache release];

コードについては、 http: //forums.macrumors.com/showthread.php?t=573253のmpramodjainの功績によるものです。

問題はこれにあるようです。SDK は iPhone で要求と応答をキャッシュします。NSMutableURLRequest cachePolicy がキャッシュから応答をロードしないように設定されているようです。

ばかげたことは、デフォルトで大量のデータをキャッシュしているように見えることです。大量のデータを (複数の接続に分割して) 送信していて、メモリの警告が表示されるようになり、最終的にアプリが停止しました。

必要なドキュメントは NSURLCache (NSURLConnection ではありません) にあり、次のように述べています。

NSURLCache は、NSURLRequest オブジェクトを NSCachedURLResponse オブジェクトにマッピングすることにより、URL 読み込み要求に対する応答のキャッシュを実装します。これは、インメモリ キャッシュとオンディスク キャッシュを組み合わせたものです。

これらの各キャッシュのサイズを操作するメソッドと、キャッシュ データの永続的なストレージに使用するディスク上のパスを制御するメソッドが提供されています。

これらの 3 行には、キャッシュを完全に削除する効果があります。それらをアプリ ( GPS ログ) に追加した後、私の #生物 カウントは安定しています。

于 2009-12-09T15:22:32.323 に答える
5

こんにちは、このデリゲートメソッドをテストしましたか?

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse
{
    return nil;
}

キャッシュをより正確に管理できます。

「リセット」NSURLCache*sharedCacheは、コードの他の部分で問題を引き起こす可能性がありますか?

于 2011-07-24T14:32:14.597 に答える
2

これはよくある質問で、[object autorelease] の魔法によって解決されます。コードでは、これは次のようになります。

NSURLConnection *theConnection = [[[NSURLConnection alloc] initWithRequest:theRequest delegate:self] autorelease];

このようにして、オブジェクトは自動的に「自動解放プール」に追加され、参照されなくなった後の次の実行ループの開始時に解放されます。

それが役立つことを願っています

編集:また、受信データ変数で -retain を呼び出す必要がある理由がわかりません。

于 2009-08-28T08:21:06.627 に答える
1

私は静的メソッド/自動解放アプローチを使用していますが、うまく機能しているようです:

[NSURLConnection connectionWithRequest:theRequest delegate:self];

この方法では、デリゲート コールバックでの解放について心配する必要さえありません。上記の例で割り当てられた後、接続の保持カウントは実際には 2 (1 ではなく) であることがわかり、このメモリ「リーク」についての私の考え方が変わりました。

@rpetrich実際には、接続が解放される前にデリゲートが解放されることを心配する必要はないと思います。接続はそのデリゲートを保持し、接続自体は実際にはある種の開いている接続キューによって保持されます。ブログで NSURLConnection を使用した実験に関するブログ投稿を書きました。

NSURLConnection での「オブジェクトのリークの可能性」

于 2012-01-07T06:40:23.830 に答える