如何将选择器或块发送到NSRunLoop来执行?

Ben*_*n S 14 iphone objective-c nsrunloop ios4 ios

我需要保证同一个线程在任意时间执行各种操作.首先,线程需要初始化一个库,然后我希望线程休眠直到需要完成工作,并且在用户输入时,我需要能够传递选择器或块来执行.

如何在初始化后设置NSRunLoop进入睡眠状态?之后,如何通知运行循环唤醒并执行某些操作?

我已经尝试过阅读iOS的线程编程指南,但是我想避免将类设置为自定义输入类并使用更轻量级的东西 performSelector:onThread:

我可以设置一个计时器从现在开始永远开火,所以运行循环不会结束吗?

这基本上是我想要的伪代码:

// Initialization Code...

do {
    sleepUntilSignaled();
    doWorkSentToThisThread();
while (!done);
Run Code Online (Sandbox Code Playgroud)

我把工作发送到哪里作为performSelector:onThread:消息.如果我可以将运行循环发送到像下面这样的块会更好:^{[someObj message]; [otherObj otherMsg];}但是我很高兴,performSelector因为我很确定没有太多额外的编码就可以实现.

谢谢!

Sve*_*ven 11

你的问题中包含了所有必要的部分.你启动你的线程并让它运行它的runloop.如果您需要线程执行某些操作,您可以performSelector:onThread:在主线程上使用它来执行此操作.

有一件事你必须要知道runloop:它不会运行,除非它有一个输入源或一个定时器连接到它.只需将一个计时器附加到运行循环中,该循环在遥远的未来会激活一段时间,并且您已完成所有设置.

// 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);
Run Code Online (Sandbox Code Playgroud)

使用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
Run Code Online (Sandbox Code Playgroud)

但也许您应该使用调度队列而不是所有这些.这需要更少的代码,并且可能还需要更少的开销:

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];
} );
Run Code Online (Sandbox Code Playgroud)

使用创建的调度队列dispatch_queue_create是一个串行队列 - 发送给它的所有块将按照它们到达的相同顺序一个接一个地执行.

  • 有时,与SQLite一样,完全相同的THREAD就是所需要的. (2认同)