2009-07-14 56 views

回答

43

每个程序至少运行一个线程。您可以将每个线程看作是一个独立的程序执行过程,每个过程与其他过程并行进行。

如果您有某种用户界面或需要监听事件的其他代码(如网络端口),则需要运行循环。每个NSThread自动获得自己的运行循环,而且你很少直接关心它们。运行循环也负责创建和释放自动释放池。

[编辑:查看关于autorelease池的更多讨论的评论。要记住的最重要的一点是新线程必须注意设置自动释放池。例如,被调用时detachNewThreadSelector(见下文)的方法应具有以下作为第一行和最后一行:

NSAutoreleasePool *pool = [ [ NSAutoreleasePool alloc ] init ]; 
    [code here] 
    [pool release]; 

这同样适用于线程使用其他技术产生了]

主线程,其中所有UI处理正在发生,运行循环非常重要,因为它使接口保持反应。这就是为什么你永远不应该在主线程上运行耗费时间的代码:它会在线程中耗尽所有时间,并且运行循环将不被允许运行得足够频繁,从而导致锁定或缓慢的接口。如果您需要执行耗时的计算,或者让任务在后台运行,则应该创建一个新线程。同样,您可能不必考虑正在创建的新运行循环。在一个新的线程中执行方法的一个简单的方法:

[NSThread detachNewThreadSelector:@selector(theSelector) toTarget:self withObject:nil]; 

线程间的通信可能会非常棘手,你应该知道的方法performSelector:onThread:withObject:waitUntilDone:performSelectorOnMainThread:withObject:waitUntilDone: (跨线程here发送NSNotifications大的提示。)

定时器也由运行循环处理。与运行循环相反,您可能经常直接在您的程序中使用计时器。创建一个计时器的非常简单的方法是:

[self performSelector:@selector(aSelector) withObject:nil afterDelay:1.0]; 

,但有时你要创建和管理的NSTimer对象自己,例如能够取消并重新使用定时器。

An NSTask用于运行另一个程序作为当前子程序的子进程。这与启动一个单独的线程有些相似,但是如果子进程崩溃,那么主程序将继续运行。程序之间的通信也与同一进程中多个线程之间的通信非常不同。

你用“iphone”标记了你的问题,而在iPhone上你永远不会使用NSTasks。当你需要处理的不同任务的大量

NSOperations使用,将它们放置在队列和/或在单独的线程处理它们(虽然他们不在单独的线程中运行)。如果您的应用程序需要创建少数专用线程,那么没有理由使用NSOperation类。但是,如果您经常会生成必须跟踪的任务(如与服务器通信),则NSOperation和NSOperationQueue将派上用场。

+0

“运行循环也负责创建和释放自动释放池。”关闭。 NSApplication这样做(在主线程上),而不是NSRunLoop。如果你生成自己的线程,你必须创建自己的池。(我引用了NSAutoreleasePool文档:“NSAutoreleasePool对象在基于应用程序工具包的应用程序的主线程中自动创建和销毁......”) – 2009-07-14 10:07:31

+0

我认为你们都错了。如果您查看样板main.m文件,* this *是创建和管理NSAutoreleasePool的位置。在我看来,runloop和autoreleasepool之间没有任何关联。 – Lounges 2009-07-14 18:02:26

4
  • NSTimer是一个计时器对象,是一种在将来调用对象选择器的方法。
  • NSThread是一个线程类。我想你知道一个线程是什么。
  • NSTask是一个进程类,用于从程序运行另一个程序。
  • NSOperation(我加入这个问题)对于单个任务来说是一个很好的抽象。您可以在此课程中嵌入您的操作,并且您可以通过NSOperationQueue课程轻松地同时执行。
  • NSRunLoop是最难理解的。以某种方式抽象和调整了unix系统调用,管理输入源以及调度线程上的事件和计时器。

准则是Apple Threading Programming Guide

3

其他答案在总结定时器,任务和线程方面做得相当不错。我想对NSRunloop做更多的评论,因为我认为大多数其他答案在这里仍然存在一些困惑。从NSRunloop文档:

一个NSRunLoop对象处理用于源,例如鼠标和键盘从窗口系统 事件,NSPORT 对象和对象NSConnection连接输入 。一个 NSRunLoop对象也处理 NSTimer事件。

一般情况下,你的应用程序不 需要创建或明确 管理NSRunLoop对象。每个 NSThread对象(包括 应用程序的主线程)都有一个 NSRunLoop对象,根据需要自动创建 。如果您需要 访问当前线程的运行循环,您可以使用类方法 currentRunLoop执行 。

将NSRunloop看作是特定线程的主要事件处理和调度循环。它从输入设备读取数据,为需要服务的任何对象提供服务,并适当地分配数据。

相关问题