14

同じスレッドが任意の時間にさまざまなアクションを実行することを保証する必要があります。最初にスレッドでライブラリを初期化する必要があります。次に、作業が完了するまでスレッドをスリープ状態にし、ユーザーの入力時にセレクターまたはブロックを渡して実行できるようにする必要があります。

初期化後に NSRunLoop をスリープするように設定するにはどうすればよいですか? その後、実行ループにウェイクアップして何かをするように通知するにはどうすればよいですか?

Threading Programming Guide for iOS を読んでみましたが、クラスをカスタム入力クラスとして設定することは避け、より軽量なものを使用したいと思いますperformSelector:onThread:

実行ループが終了しないように、タイマーを今から永久に起動するように設定できますか?

基本的に、擬似コードで必要なものは次のとおりです。

// Initialization Code...

do {
    sleepUntilSignaled();
    doWorkSentToThisThread();
while (!done);

仕事をperformSelector:onThread:メッセージとして送信する場所。次のようなブロックを実行ループに送信できればさらに良いでしょ^{[someObj message]; [otherObj otherMsg];}performSelector

ありがとう!

4

3 に答える 3

11

あなたの質問には、必要な要素がすべて揃っています。スレッドを開始し、runloop で実行します。何かを行うためにスレッドが必要な場合はperformSelector:onThread:、メインスレッドで使用できます。

ただし、runloop には、注意しなければならないことが 1 つあります。それは、入力ソースまたはタイマーが接続されていない限り、実行されないということです。遠い将来のある時点で起動する実行ループにタイマーを接続するだけで、準備は完了です。

// Initialization code here

[NSTimer scheduledTimerWithTimeInterval: FLT_MAX
                                 target: self selector: @selector(doNothing:)
                               userInfo: nil repeats:YES];

NSRunLoop *rl = [NSRunLoop currentRunLoop];
do {
    [rl runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
} while (!done);

を使用performSelector:onThread:withObject:すると、ブロックをバックグラウンド スレッドに渡すこともできます。必要なのは、ブロックをパラメーターとして取り、それを実行するメソッドをどこかに記述することだけです。

@interface NSThread (sendBlockToBackground)
- (void) performBlock: (void (^)())block;
@end

@implementation NSThread (sendBlockToBackground)
- (void) performBlock: (void (^)())block;
{
    [self performSelector: @selector(runBlock:) 
                 onThread: self withObject: block waitUntilDone: NO];
}

- (void) runBlock: (void (^)())block;
{
    block();
}
@end

しかし、これらすべての代わりにディスパッチ キューを使用する必要があるかもしれません。これにより必要なコードが少なくなり、おそらくオーバーヘッドも少なくなります。

dispatch_queue_t myQueue = dispatch_queue_create( "net.example.product.queue", NULL );
dispatch_async( myQueue, ^{
    // Initialization code here
} );

// Submit block:
dispatch_async( myQueue, ^{
    [someObject someMethod: someParameter];
} );

を使用して作成されたディスパッチ キューdispatch_queue_createは、シリアル キューです。送信されたすべてのブロックは、到着した順序で次々と実行されます。

于 2010-10-15T08:50:24.497 に答える
2

NSConditionLock の使用を検討してください。このようなタスク用に設計されています。データを含むキューがあるとします。最初のスレッドはデータをキューに追加し、2 番目のスレッドはデータを待機して処理します。

id condLock = [[NSConditionLock alloc] initWithCondition:NO_DATA];

//First thread
while(true)
{
    [condLock lock];
    /* Add data to the queue. */
    [condLock unlockWithCondition:HAS_DATA];
}

//Second thread
while (true)
{
    [condLock lockWhenCondition:HAS_DATA];
    /* Remove data from the queue. */
    [condLock unlockWithCondition:(isEmpty ? NO_DATA : HAS_DATA)];

    // Process the data locally.
}
于 2011-12-23T01:05:09.513 に答える
0

NSOperationQueue でNSInvocationOperationを使用できると思います。

于 2010-10-15T08:39:17.200 に答える