ios - NSRunLoop 是做什么的?

标签 ios port nsthread nsrunloop

我读了很多关于 NSRunLoop 的帖子,比如 this , this , this .但无法弄清楚 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是用来管理事件的,为什么在threadProc里面除了调用runMode就什么都没有了?

最佳答案

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

因为:

  • 您创建的 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

关于ios - NSRunLoop 是做什么的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16477433/

相关文章:

ios - OneSignal + React Native + 后台通知

c# - xamarin.ios mp3 在屏幕关闭时停止播放

c# - 在某个端口上查找传出连接的 IP 地址

python - selenium.common.exceptions.WebDriverException : Message: 'Can not connect to GhostDriver'

ios - 仅在一个托管上下文中保存其他托管对象上下文中没有更改

ios - 在 dispatch_queue_t 上调用执行是否确保它们在同一个线程上?

ios - 如何在 Swift 3.0 中调用 REST 服务

ios - lproj 文件尚未加载

google-app-engine - 更改默认端口 8080 maven gae 目标 appengine :devserver

ios - 通过线程调用函数给出异常