Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/99.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone NSTimer、NSTask、NSThread和nsrunlop之间的基本区别是什么?_Iphone_Ios_Multithreading_Cocoa - Fatal编程技术网

Iphone NSTimer、NSTask、NSThread和nsrunlop之间的基本区别是什么?

Iphone NSTimer、NSTask、NSThread和nsrunlop之间的基本区别是什么?,iphone,ios,multithreading,cocoa,Iphone,Ios,Multithreading,Cocoa,NSTimer、NSTask、NSThread和nsrunlop之间有什么区别?是否有关于何时使用它们的指南?每个程序至少在一个线程中运行。您可以将每个线程看作是一个单独的程序执行过程,每个线程与其他线程并行运行 如果您有某种用户界面或其他需要侦听事件的代码(如网络端口),则需要一个运行循环。每个NSThread都会自动获得自己的运行循环,您很少需要直接关注它们。运行循环还负责创建和释放自动释放池 [编辑:有关自动释放池的更多讨论,请参阅注释。需要记住的最重要一点是,新线程必须负责设置自动释放池

NSTimer
NSTask
NSThread
nsrunlop
之间有什么区别?是否有关于何时使用它们的指南?

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

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

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

   NSAutoreleasePool *pool = [ [ NSAutoreleasePool alloc ] init ];
   [code here]
   [pool release];
这同样适用于使用其他技术生成的线程。]

在执行所有UI处理的主线程中,运行循环非常重要,因为它保持界面的反应性。这就是为什么您永远不应该在主线程上运行耗时的代码:它会占用线程上的所有时间,并且运行循环的运行频率不够高,从而导致接口被锁定或速度较慢。如果需要执行耗时的计算,或者让任务在后台运行,那么应该创建一个新线程。同样,您可能不必考虑创建新的运行循环。在新线程中执行方法的简单方法:

[NSThread detachNewThreadSelector:@selector(theSelector) toTarget:self withObject:nil];
线程间通信可能很棘手,您应该了解方法
performSelector:onThread:withObject:waituntldone:
performSelector-onmainthread:withObject:waituntldone:
(关于跨线程发送通知的好提示。)

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

[self performSelector:@selector(aSelector) withObject:nil afterDelay:1.0];
但有时您希望自己创建和管理NSTimer对象,例如,能够取消并重新使用计时器

NSTask用于将另一个程序作为当前程序的子进程运行。这有点类似于启动单独的线程,但如果子进程崩溃,主程序将继续运行。程序之间的通信与同一进程中多个线程之间的通信也有很大不同

您将问题标记为“iphone”,在iphone上您将永远不会使用NSTASK

NSOperations用于处理大量不同的任务,将它们放入队列和/或在单独的线程中处理(尽管它们不必在单独的线程中运行)。如果应用程序只需要创建几个专用线程,那么就没有理由使用NSOperation类。但是,如果您将定期生成必须跟踪的任务(如与服务器通信),NSOperation和NSOperationQueue将派上用场。

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

指南是。其他答案在总结计时器、任务和线程方面做得相当好。我想对nsrunlop多加评论,因为我认为大多数其他答案在这里仍然留下一些混乱。从nsrunlop文档中:

NSRunLoop对象处理输入 用于鼠标和键盘等源 来自窗口系统的事件,NSPort 对象和非连接对象。一 NSRunLoop对象还处理 NSTimer事件

一般来说,您的应用程序不会 需要创建或显式地 管理nsrunlop对象。每个 NSThread对象,包括 应用程序的主线程,具有 自动创建的nsrunlop对象 如果需要的话。如果你需要 访问当前线程的运行循环, 您可以使用类方法来实现这一点 当前运行循环


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

您可能还对NSOperation感兴趣。“运行循环还负责创建和释放自动释放池。”关闭。NSApplication(在主线程上)执行此操作,而不是nsrunlop。如果生成自己的线程,则必须创建自己的池。(我引用了NSAutoreleasePool文档:“NSAutoreleasePool对象在基于应用程序工具包的应用程序主线程中自动创建和销毁…”)我认为你们都错了。如果查看样板文件main.m文件,就可以在这里创建和管理NSAutoreleasePool。正如我所知,运行循环和自动释放池之间没有相关性。运行循环有一个自动释放池,它在每个循环中都会耗尽。Napplication无法承担责任,因为它无法将其排出,并且它没有