NSTimer,NSTask,NSThread和NSRunloop之间的基本区别是什么?

Pra*_*u R 27 iphone cocoa multithreading ios

是什么区别NSTimer,NSTask,NSThread而且NSRunloop,是有关于何时使用它们中的每一个准则?

Fel*_*xyz 43

每个程序至少在一个线程中运行.您可以将每个线程视为一个独立的程序执行过程,每个过程都与其他线程并行运行.

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

[编辑:有关自动释放池的更多讨论,请参阅注释.要记住的最重要的一点是新线程必须注意设置自动释放池.例如,使用detachNewThreadSelector调用的方法(见下文)应该包含以下第一行和最后一行:

   NSAutoreleasePool *pool = [ [ NSAutoreleasePool alloc ] init ];
   [code here]
   [pool release];
Run Code Online (Sandbox Code Playgroud)

这同样适用于使用其他技术生成的线程.]

主线程中,所有UI处理都在进行,运行循环非常重要,因为它使接口保持活动状态.这就是为什么你永远不应该在主线程上运行耗时的代码:它会在线程上耗尽所有时间并且不允许运行循环经常运行,从而导致锁定或慢速接口.如果您需要执行耗时的计算,或者让任务在后台运行,您应该创建一个新线程.同样,您可能不必考虑正在创建的新运行循环.在新线程中执行方法的简单方法:

[NSThread detachNewThreadSelector:@selector(theSelector) toTarget:self withObject:nil];
Run Code Online (Sandbox Code Playgroud)

线程间通信可能很棘手,你应该知道这些方法performSelector:onThread:withObject:waitUntilDone:performSelectorOnMainThread:withObject:waitUntilDone: (在这里跨线程发送NSNotification的好技巧.)

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

[self performSelector:@selector(aSelector) withObject:nil afterDelay:1.0];
Run Code Online (Sandbox Code Playgroud)

但有时你想自己创建和管理NSTimer对象,例如能够取消和重新使用计时器.

一个NSTask用于运行的另一个程序,则当前的子进程.它有点类似于启动一个单独的线程,但如果一个子进程崩溃,你的主程序将继续运行.程序之间的通信也与同一进程中多个线程之间的通信非常不同.

你用"iphone"标记你的问题,在iPhone上你将永远不会使用NSTasks.

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

  • Cocoa应用程序项目模板不会在`main`中创建自动释放池.它只是尾调用`NSApplicationMain`.NSApplication确实创建了一个自动释放池 - 这在NSApplication和NSAutoreleasePool的文档中都是*明确记录的*.此外,"线程编程指南"明确指出,如果创建线程,则必须创建自动释放池(http://developer.apple.com/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/chapter_4_section_5.html#//apple_ref/ doc/uid/10000057i-CH15-SW14). (4认同)