0

PerformSelectorInBackgroundを使用してセレクターをバックグラウンドスレッドで起動するようにNSInovcationシステムをセットアップしようとしています:-これまでのところ、インスタンスメソッド(-)でシステムを実行するとすべてが成功しますが、クラスメソッド(+)もサポートしたいと思います。両方のタイプのクラスにinvokeInBackgroundThreadを提供するようにコードを調整し、1つの問題を除いてすべてが機能しました。クラスメソッドが呼び出されると、コンソールに「プールが配置されていない状態で自動解放されました」というメッセージが殺到します。何が原因なのかわかりません。DDFoundationオープンソースプロジェクトに基づくコードを以下に示します。


@implementation NSObject (DDExtensions)
...
+ (id)invokeInBackgroundThread
{
    DDInvocationGrabber *grabber = [DDInvocationGrabber invocationGrabber];
    [grabber setInvocationThreadType:INVOCATION_BACKGROUND_THREAD];
    return [grabber prepareWithInvocationTarget:self];
}

- (id)invokeInBackgroundThread
{
    DDInvocationGrabber *grabber = [DDInvocationGrabber invocationGrabber];
    [grabber setInvocationThreadType:INVOCATION_BACKGROUND_THREAD];
    return [grabber prepareWithInvocationTarget:self];
}
...

...
- (void)forwardInvocation:(NSInvocation *)ioInvocation
{
    [ioInvocation setTarget:[self target]];
    [self setInvocation:ioInvocation];

 if (_waitUntilDone == NO) {
  [_invocation retainArguments];
 }

    if (_threadType == INVOCATION_MAIN_THREAD)
    {
        [_invocation performSelectorOnMainThread:@selector(invoke)
                                      withObject:nil
                                   waitUntilDone:_waitUntilDone];
    } else {
        [_invocation performSelectorInBackground:@selector(invoke)
                                  withObject:nil];
 }
}
...

+(void)doSomething;
[[className invokeOnBackgroundThread] doSomething];
4

1 に答える 1

1

追加のスレッドを開始した場合、メインスレッドにはデフォルトで自動解放プールがあります。プールを作成するのはあなたの仕事です。実際、ここでは複雑なことは何もありません。

NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
// Work...
[pool release];

また、スレッドが多い場合は、[performSelectorInBackground]でスレッドを実行するのではなく、NSOperationを確認することをお勧めします。NSOperation(ラッピングキューを使用)は、このようなタスクに対してより柔軟なソリューションです。

于 2010-08-27T13:21:02.137 に答える