2013-05-10 63 views
5

我读了很多关于NSRunLoop的帖子,如this,this,this。但不能找出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]; 
} 

和主线程通过一些工作,这线程

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

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

我看过NSRunLoop是用来管理事件的,为什么除了调用runModethreadProc之内呢?

+0

我认为它是一个幻想,而(真){//插入要在这里完成的工作},其中你可以动态添加要执行的代码(事件,工作,套接字等)。 runloop不是真的是空的,一个端口已经连接到runloop,它是进程间通信的一种形式。 – foFox 2013-05-10 07:56:00

+0

我发现这个http://bou.io/RunRunLoopRun.html也是有用的 – onmyway133 2015-06-17 17:17:44

回答

3

您展示的示例是一个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 
+0

1)那为什么threadProc里面有while循环呢? 2)GCD将把工作转移到任何可用/未知的线程,但NSRunLoop将确保所有工作都将转移到同一个工作线程,对吗? – onmyway133 2013-05-12 00:57:47

+0

提供终止运行循环的机制 - 当设置'isStopped'标志时(尽管这在代码中没有显示出来......) – FluffulousChimp 2013-05-12 09:09:12

+0

2)请参阅针对您所描述的用例的GCD方法的编辑答案。 – FluffulousChimp 2013-05-12 09:22:05

3

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

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

对于真正好奇的是github上有示例代码,您可以使用循环运行 - 添加一条评论,然后列出一些代码。

+0

1)但在threadProc中,有一个while循环,所以线程总是忙? NSRunLoop如何告诉它停止执行? 2)AFAIK,这是一个机制,以确保许多调用performSelector:onThread:将工作转移到同一个工作线程,对吧? – onmyway133 2013-05-11 03:52:12

+0

1)抱歉,不清楚 - 操作系统将暂停runMode中的线程:如果没有任何代码需要处理。 2)它是系统的一个功能 - 但还有其他功能 - 端口和定时器处理。通过阅读CFRunloop上的苹果文档,您将学到最多 - 我相信这有一个指南。 – 2013-05-11 11:45:17