2009-08-30 6 views
1

fetchHTMLが別のスレッドで呼び出されていると言えば、もっと明るくなるでしょうか?stringWithContentsOfURLメモリが漏れている

_NSAutoreleaseNoPool()::私はまたのようなデバッグコンソールで複数のメッセージを見ていたクラスNSCFDictionaryのオブジェクト0xd92860は、所定の位置にいないプールで自動解放 - ちょうど

_NSAutoreleaseNoPoolを(漏れた):クラスNSCFStringのオブジェクト0xd92800はで自動解放しましたプールがない - ちょうど漏れている

私はiPhoneアプリの開発、Objective-Cには新しいが、プログラミングやC/C++には新しくない。私はリーク性能ツールを使用しており、多くのリークを示しています。これは、10.5キロバイト漏れであり、それはライン上で発生します。以下この上

NSString * xml = [NSString stringWithContentsOfURL:urlobj]; 

スタックトレースは次のとおりです。

stringWithContentsOfURL 
initWithContentsOfURL 
initWithDataOfEncoding 
... 

は、誰もがこれが起こってなければならない理由のアイデアを持っています。私はここでオートレリーズオブジェクトを取得しているという印象を受けており、コールを保持せずにこれを呼び出し元に返すことができます。私は、xmlオブジェクトをインスタンス変数に格納するために、処理のためだけに使用していません。ここ

は機能コードである:

- (NSString *) fetchHTML: (NSString*) url{ 
    @try 
    { 
     NSURL* urlobj = [NSURL URLWithString:url]; 
     NSString * xml = [NSString stringWithContentsOfURL:urlobj]; 
     return xml; 
    } 
    @catch(NSException *ex){ 
     NSLog(@"Error fetchingHTML"); 
     return nil; 
    } 
    return nil; 
} 
+0

「fetchHTMLが別のスレッドで呼び出されていると言ったら、もっと明るくなっていますか?」あなたはドキュメントに従って、スレッド用の自動解放プールを作成しましたか?できればそうでないにしても、スポーンされたスレッドのメソッド/ファンクション・エントリー・ポイントで最初に行うことの1つです。 – johne

答えて

1

うん。それは漏れてはいけません。

URLサブシステムがURLの内容をキャッシュし、ポインタがもはやリーク分析のために見えないようにしているという点で、偽陽性かもしれません。

可能であれば、Snow Leopardでテストを再試行してください。 Snow Leopardのリーク検出は、はるかに高速で正確です。

1

私はリークを引き起こしてはならないと完全に同意します。私は2年前からCocoa/Objective-Cでコーディングしていましたが、それはうまくいくはずです。

Appleのドキュメントには、stringWithContentsOfURL:の方法がdeprecatedであることが示されています。おそらく、次のように動作します:

NSString * xml = [[NSString alloc] 
        initWithContentsOfURL:urlobj 
           encoding:NSASCIIStringEncoding 
            error:nil]; 
return [xml autorelease]; 
+0

私は間違いなくそれを試みることができます。それはいくつかの光を介して、別のスレッドでfetchHTMLが呼び出されていることを伝えましたか?新しいオートリリースルームを作成する必要がありますか? 私のデバッグコンソールでは、 "クラス***のオブジェクト****のようないくつかのメッセージが表示されます。場所にプールはありません。ただ漏れています。 –

+0

私はオートリリースプールのスレッド使用について熟練していません。 。*? NSAutoreleasePool:それはしかし、なぜ質問には、その情報を追加しないで、問題になる可能性のような音ん –

1

エラーメッセージには、文字列の自動解放プールがないため、リークが発生することがわかります。 NSAutoreleasePoolsはスレッドごとに存在します。 Cocoaはメインスレッドのメインイベントループに1つ作成しますが、それはあなたのために作成する唯一のものです。メインスレッド以外の場所でオートレリースされたオブジェクトを扱う場合は、そのスレッド用の自動解放プールも作成する必要があります。

自動解放プールスタックの動作の詳細については、NSAutoreleasePool docsを参照してください。

+0

おかげで、私は私のスレッド関数の周りautoreleasepoolラッパーを追加しましたが、私はobjc_msgSendのエラーを取得する をここでは、コードです。 pool = [[NSAutoreleasePool alloc] init]; [dataArray replaceObjectAtIndex:2 withObject: "now what"]; [プールの解放]; ここで何が起こっているのでしょうか? –

+0

[dataArray replaceObjectAtIndex:2 withObject:@ "now what"]; @記号に注意してください。 –

+0

実際、replaceObjectAtIndex ...行は、自動解放プールが存在する前に動作していない可能性があります。 – Chuck

関連する問題