2011-01-24 14 views
3

私は新しいスレッドを生成するために[NSThread detachNewThreadSelector]を使用していますが、コンソールに「autoreleased no pool in place」エラーが表示されています。私はあなたが自動リリースプールを作成しなければこれが起こることがあることを知っていますが、事は、私はそれを作成しています。私は同じアプリケーションの他の部分で同様のコードを使用し、これらのエラーを取得しないでください。iOSは自動リースされ、プールはありませんが、ARPを作成しています!

ここ関連するコードである:

- (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オブジェクトを作成し、それらのすべてが同様に報告します。

役立つヒントやポインタに感謝します。

ありがとうございます!

答えて

5

新しいスレッドを作成するときには、新しいスレッドを作成する必要があります。

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

loadImageFromURL:

[pool drain]; 

の冒頭で終わり:あなたのケースでは、それは追加のと同じくらい簡単に見えます。

おそらく、作成するプールはstartThread:には必要ないでしょう。 Threading Programming Guide、特に「スレッドエントリルーチンの作成」を参照してください。

+0

カール - 私はあなたの時間を無駄にすることをお詫び申し上げます。あなたは正しいのです。それは、私がdetachNewThreadSelectorを使うアプリケーションの他の部分でどうやってやっているかです。ちょうど木の森を見ることができませんでした。私は間違ったパターンに固定されていて、他のコードを見たことがないので、同じであると確信していました。早速の対応、ありがとうございました! – Jordan

4

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

メインスレッドには既にNSAutoreleasePoolが含まれているため、startThread:に作成するスレッドはおそらく不要です。しかし、バックグラウンドスレッドはNSAutoreleasePoolを作成しないので、自分で作成する必要があります。 @Carl Norumはあなたがautorelelaseプールを使用して行われたときに、あなたが代わりにreleasedrainを使用する必要があり、提案として、

また
- (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]; 
} 

:次のようになり、あなたのコードで

、。

+0

WRTはドレイン対放出を使用しています - 私の読書のすべては、(iOS上で)彼らが均等であることを私に示しています。私がそれらの間で見つけることができる唯一の違いは、ドレインがiOS上に存在しないGCサブシステムにヒントを提供することです。別の理由はありますか? – Jordan

+0

私はそこにいるとは思わない。 – pgb

+1

iOS 5または6でガベージコレクションがうまく行えるこ​​とを忘れないでください。それはまた、誰でも知っている無料のトーストを持つことができます。 –

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 
    } 
}