Ios NSRunLoop做什么?

Ios NSRunLoop做什么?,ios,port,nsthread,nsrunloop,Ios,Port,Nsthread,Nsrunloop,我读了很多关于nsrunlop的帖子,比如。但无法了解nsrunlop的实际功能 我通常看到的是工作线程 wthread = [[NSThread alloc] initWithTarget:self selector:@selector(threadProc) object:nil]; [wthread start]; 里面有一个nsrunlop - (void)threadProc { NSAutoreleasePool* pool1 = [[NSAutoreleasePoo

我读了很多关于
nsrunlop
的帖子,比如。但无法了解nsrunlop的实际功能

我通常看到的是工作线程

wthread = [[NSThread alloc] initWithTarget:self selector:@selector(threadProc) object:nil];  
[wthread start];
里面有一个nsrunlop

- (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];
在将工作从主线程传递到工作线程方面,我看到很多人都这样做。为什么需要在这里卸载nsrunlop?它有什么作用


我读到
nsrunlop
用于管理事件,为什么除了在
threadProc
内部调用runMode之外什么都没有呢?

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

没有很好的文档记录的是,当您发送performSelector:onThread:…,是运行循环对消息进行排队,唤醒让线程处理它。如果将日志消息添加到while循环中,则可以看到这种情况


对于真正好奇的人来说,github上有一个示例代码,你可以使用运行循环-添加一条注释,我将列出一些注释。

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

因为:

  • 您创建的
    nsrunlop
    实例至少有一个输入源(
    [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

我认为这是一种幻想,而(真的){//insert job to done here},在这里您可以动态添加要执行的代码(事件、工作、套接字等)。runloop不是真的空的,一个端口已经连接到runloop,这是进程间通信的一种形式。我发现这也很有用1)但是在threadProc内部,有一个while循环,所以线程总是很忙?NSRunLoop如何告诉它停止执行?2) 好吧,这是一种机制,可以确保对performSelector:onThread:的多次调用会将工作转移到同一个工作线程,对吗?1)很抱歉,不清楚-如果代码没有任何可处理的内容,操作系统将在运行模式内挂起该线程。2) 这是系统的一个特性,但也有其他特性——端口和定时器处理。通过阅读CFRunloop上的苹果文档,你会学到很多东西——我相信有一个指南。1)那么为什么threadProc中有while loop呢?2) GCD将把工作转移到任何可用/未知的线程,但nsrunlop将确保所有工作都转移到同一个工作线程,对吗?以提供终止运行循环的机制-当设置标志
isStopped
时(尽管代码中未显示该标记…)2) 请参阅您正在描述的用例的GCD方法的编辑答案。dispatch_queue是否确保在同一线程中连续完成2项工作?@onmyway133无串行队列不保证在同一线程中完成所有块。它只允许串行执行