3

そのため、[NSThread detachNewThreadSelector] を使用して新しいスレッドを生成すると、コンソールに「プールが配置されていない状態で自動解放されました」というエラーが表示されます。自動解放プールの作成に失敗すると、これが発生する可能性があることはわかっていますが、問題は、私が作成していることです。同じアプリの他の部分で同様のコードを使用していますが、これらのエラーは発生しません。

関連するコードは次のとおりです。

- (void) startThread:(NSString*)strURL
{
    // start new thread to load image
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    [NSThread detachNewThreadSelector:@selector(loadImageFromURL:) toTarget:self withObject:strURL];
    [pool release];
}

- (void) loadImageFromURL:(NSString*)strURL
{
    NSNumber* nn = [NSNumber numberWithInt:self.tag];
    NSLog(@"loadURL: Tag number == %i", [nn intValue]);

   // other code here actually does the work
}

さて、(リモート サーバーからイメージをロードする) 実際に作業を行う loadImageFromURL にさらに多くのコードがありましたが、そのコードがなくても問題が明らかになるので、削除しました (私が持っていると思わないように)何もしない無意味なスレッド!)。問題を示すコードを 1 行だけ残しました。自動解放された NSNumber オブジェクトを作成します。

このコードを実行すると、コンソールに次のように報告されます。

__NSAutoreleaseNoPool(): Object 0x535c0e0 of class NSCFNumber autoreleased with no pool in place - just leaking

もちろん、実際のコードは他の多くの AR オブジェクトを作成し、それらすべても同様に報告されます。

役に立つかもしれないヒントや指針に感謝します!

ありがとう!

4

3 に答える 3

5

新しいスレッドを作成するときは、そのスレッド用の新しい自動解放プールも作成する必要があります。あなたの場合、それは追加するのと同じくらい簡単に見えます:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

の初めloadImageFromURL:

[pool drain];

最後に。

作成しているプールはおそらく必要ないか、必要ありませんstartThread:スレッドプログラミングガイド、特に「スレッドエントリルーチンの作成」セクションを確認してください。

于 2011-01-24T18:30:10.133 に答える
4

あなたのコードで- (void) startThread:(NSString*)strURLは、メインスレッドで- (void) loadImageFromURL:(NSString*)strURL実行されていますが、デタッチしているバックグラウンドスレッドで実行されています。

メインスレッドにはすでに があるNSAutoreleasePoolため、作成しているスレッドstartThread:はおそらく不要です。ただし、バックグラウンド スレッドは を作成しないため、NSAutoreleasePool自分で作成する必要があります。

コードでは、次のようになります。

- (void) startThread:(NSString*)strURL
{
    // start new thread to load image
    [NSThread detachNewThreadSelector:@selector(loadImageFromURL:) toTarget:self withObject:strURL];
}

- (void) loadImageFromURL:(NSString*)strURL
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    NSNumber* nn = [NSNumber numberWithInt:self.tag];
    NSLog(@"loadURL: Tag number == %i", [nn intValue]);

   // other code here actually does the work

    [pool drain];
}

また、@Carl Norum が示唆したように、自動解放プールの使用が終了したときdrainの代わりに使用する必要があります。release

于 2011-01-24T18:34:26.280 に答える
1

同様の問題の解決策ですが、ARCを使用しています。

ARC を使用している場合、「'NSAutoreleasePool' は使用できません: 自動参照カウント モードでは使用できません」というエラーが発生する可能性があります。

使用する:

- (void) startThread:(NSString*)strURL
{
    // start new thread to load image
    [NSThread detachNewThreadSelector:@selector(loadImageFromURL:) toTarget:self withObject:strURL];
}

- (void) loadImageFromURL:(NSString*)strURL
{
    @autoreleasepool {          
        NSNumber* nn = [NSNumber numberWithInt:self.tag];
        NSLog(@"loadURL: Tag number == %i", [nn intValue]);

        // other code here actually does the work   
    }
}
于 2012-10-29T06:43:19.343 に答える