6

我读了很多关于NSRunLoop,像这样这样这样的帖子。但无法弄清楚NSRunLoop实际上是做什么的

我通常看到的是一个工作线程

wthread = [[NSThread alloc] initWithTarget:self selector:@selector(threadProc) object:nil];  
[wthread start];

里面有一个 NSRunLoop

- (void)threadProc 
{
    NSAutoreleasePool* pool1 = [[NSAutoreleasePool alloc] init];
    BOOL isStopped = NO;
    NSRunLoop *runloop = [NSRunLoop currentRunLoop];
    [runloop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];

    while (!isStopped)
    {
        {
            NSAutoreleasePool* pool2 = [[NSAutoreleasePool alloc] init];
            [runloop runMode:NSDefaultRunLoopMode
                                      beforeDate:[NSDate distantFuture]];

            [pool2 release];
        }
    }

    [pool1 release];
}

主线程将一些工作传递给这个 wthread

[self performSelector:@selector(someWork:) onThread:wthread withObject:nil waitUntilDone:NO];

在将工作从主线程传递到工作线程方面,我看到很多人这样做。为什么这里需要 NSRunLoop ?它有什么作用 ?

我读的NSRunLoop是用来管理事件的,为什么除了在里面调用runModethreadProc什么都没有?

4

2 回答 2

5

-threadProc您展示的示例是一个 Cocoa 习惯用法,用于创建在方法退出后将继续运行的线程。为什么?

因为:

  • NSRunLoop您创建的实例至少有一个输入源 ( [NSMachPort port])
  • 你已经明确地启动了运行循环runMode:beforeDate

如果不添加输入源并显式启动运行循环,线程将终止。

顺便说一句,尽管运行循环对于管理事件和某些异步任务仍然至关重要,但我不会将NSThread其视为当今在 Cocoa 应用程序中构建大多数异步工作的默认方式。GCD 是一种更简洁的封装后台工作的方式。

编辑

将工作提交到 GCD 中的串行队列:

@interface Foo : NSObject
@end

@implementation Foo {
    dispatch_queue_t _someWorkerQueue;
}

- (id)init {
    self = [super init];
    if( !self ) return nil;

    _someWorkerQueue = dispatch_queue_create("com.company.MyWorkerQueue", 0);
    return self;
}

- (void)performJob {
    dispatch_async(_someWorkerQueue, ^{
        //do some work asynchronously here
    });

    dispatch_async(_someWorkerQueue, ^{
        //more asynchronous work here
    });
}
@end
于 2013-05-11T14:56:13.583 回答
4

幕后发生了很多事情。这样做的原因是它为线程在没有工作项时停止执行提供了一种方法。如果您曾经使用过实时操作系统,那么任务需要一个地方来放弃处理器,以便其他人可以运行。

没有充分记录的是,当您发送 performSelector:onThread:... 时,运行循环将消息排队并唤醒以让线程处理它。如果您将日志消息添加到 while 循环中,您会看到这种情况发生。

对于真正好奇的人,您可以在 github 上使用示例代码来玩运行循环 - 添加评论,我会列出一些。

于 2013-05-10T12:29:48.293 回答