4

このコードを見てください:

@interface myObject:NSObject

-(void)function:(id)param;

@end

@implementation myObject

-(void)function:(id)param
{
    NSLog(@"BEFORE");
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:20]];
    NSLog(@"AFTER");
}

@end


int main(int argc, char *argv[])
{
    myObject *object = [[myObject alloc] init];

    [NSThread detachNewThreadSelector:@selector(function:) toTarget:object withObject:nil];

    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

functionメソッドが呼び出されますが、20 秒間の一時停止はありません。NSRunLoop切り離されたスレッドで作業するにはどうすればよいですか?

4

1 に答える 1

4

function:別のスレッドでセレクターを実行しているため[NSRunLoop currentRunLoop]、メインスレッドと同じではありません。

NSRunLoop リファレンスを参照してください:

実行ループに入力ソースまたはタイマーが接続されていない場合、このメソッドはすぐに終了します。

実行ループが空であるため、「BEFORE」および「AFTER」ログが即座に表示されると思います。

あなたの問題に対する簡単な解決策は

@implementation myObject

-(void)function:(id)param
{
  NSLog(@"BEFORE");
  [[NSRunLoop currentRunLoop] addTimer:[NSTimer timerWithTimeInterval:20 selector:... repeats:NO] forMode:NSDefaultRunLoopMode];
  [[NSRunLoop currentRunLoop] run];
  NSLog(@"AFTER");
}

@end

実際には、タイマーによって呼び出される新しいメソッドに「AFTER」を記録するコードを配置することになるでしょう。一般に、アニメーションを実行するためにスレッドは必要ありません (計算コストの高い処理を行う場合を除きます)。計算コストの高い作業を行っている場合は、Grand Central Dispatch (GCD) の使用も検討する必要があります。これにより、バックグラウンド スレッドでのオフロード計算が簡素化され、配管が処理されます。

于 2012-03-22T10:01:36.933 に答える