1

Objective-C でのスレッド化についてもっと学びたいと思ったので、ループしてループの繰り返しを出力する小さなテスト プログラムを作成しました。ただし、得られる出力は期待したものではありません。理由については考えがありますが、最初に私のコードを次に示します。

main.m

#import <Foundation/Foundation.h>
#import "Car.h"


int main(int argc, const char * argv[])
{

    @autoreleasepool {
        Car* myCar = [[Car new] autorelease];

        [myCar performSelectorInBackground:@selector(LoopAndSay) withObject:nil];

        for(int i = 0; i < 100; i++ )
        {

            NSLog(@"Main loop on %i", i);
        }


    }
return 0;
}

車.m

#import "Car.h"

@implementation Car
@synthesize name, model;

-(void) LoopAndSay {

    for(int i = 0; i < 100; i++)
    {
        NSLog(@"Looping for the %i time", i);

    }

}
@end

ここで、そのまま実行すると、バックグラウンド ループが完了しないことがあります (反復 94 と 97 の間で停止します)。さらに、バックグラウンド ループがメイン スレッド ループの後まで呼び出されないようにコードを切り替えると、反復は実行されません。これは、メイン スレッドが終了していて、バックグラウンド スレッドの実行が完了するのを待ちたくないためですか? この場合、メイン スレッドとバックグラウンド スレッドの両方が完了するまでプログラムを強制的に実行し続ける方法はありますか?

4

2 に答える 2

3

これは、バックグラウンド スレッドが完了する前に関数が返される前に、スレッドが完了する前に自動解放プールのスコープを終了するためです。終了前にまたは何かmainを追加して、バックグラウンド スレッドが完了するかどうかを確認してください。sleep(3)

Mac OS X では、すべての「フォアグラウンド」スレッドが完了するとプロセスが終了します。peformSelectorInBackground:バックグラウンドスレッドのみを作成するため、main戻ると、フォアグラウンドスレッドがなくなり、プロセスが終了します。

于 2013-04-08T18:47:33.363 に答える
3

これは、performSelectorInBackground:...およびその他の Objective-C API で作成されたすべてのスレッドがdetachedであるため、プログラムはそれらの終了を待たずに終了できるためです。スレッディングプログラミングガイドから:

アプリケーションの終了時に、切り離されたスレッドはすぐに終了できますが、結合可能なスレッドは終了できません。[...] 参加可能なスレッドを作成したい場合、唯一の方法は POSIX スレッドを使用することです...

この場合、メイン スレッド ループがバックグラウンド スレッドよりも少し早く終了するため、バックグラウンド スレッド ループは最後まで実行されません。POSIX スレッド (あまり便利ではありません) を使用する代わりに、 を使用することもできますNSOperationQueue。これにより、キュー内のすべての操作が終了するのを簡単に待つことができます。

于 2013-04-08T18:50:29.630 に答える