NSTimer
、NSTask
、NSThread
和 NSRunloop
之间有什么区别,是否有关于何时执行的指南使用它们中的每一个?
最佳答案
每个程序至少在一个线程中运行。您可以将每个线程视为一个独立的程序执行进程,每个线程都与其他线程并行运行。
如果您有某种用户界面或其他代码需要监听事件(如网络端口),您需要一个运行循环。每个 NSThread 都会自动获得自己的运行循环,你很少需要直接关心它们。运行循环还负责创建和释放自动释放池。
[编辑:有关自动释放池的更多讨论,请参阅评论。要记住的最重要的一点是新线程必须负责设置自动释放池。例如,使用 detachNewThreadSelector(见下文)调用的方法的第一行和最后一行应包含以下内容:
NSAutoreleasePool *pool = [ [ NSAutoreleasePool alloc ] init ];
[code here]
[pool release];
这同样适用于使用其他技术生成的线程。]
在所有 UI 处理发生的主线程中,运行循环非常重要,因为它使界面保持 react 性。这就是为什么你永远不应该在主线程上运行耗时的代码:它会耗尽线程上的所有时间并且不允许运行循环运行足够频繁,从而导致锁定或缓慢的接口(interface)。如果你需要执行耗时的计算,或者让一个任务在后台运行,你应该创建一个新线程。同样,您可能不必考虑创建新的运行循环。在新线程中执行方法的简单方法:
[NSThread detachNewThreadSelector:@selector(theSelector) toTarget:self withObject:nil];
线程间通信可能很棘手,您应该了解方法 performSelector:onThread:withObject:waitUntilDone:
和 performSelectorOnMainThread:withObject:waitUntilDone:
(关于跨线程发送 NSNotifications 的重要提示 here。)
计时器 也由运行循环处理。与运行循环相反,您可能经常在程序中直接使用计时器。创建计时器的最简单方法是:
[self performSelector:@selector(aSelector) withObject:nil afterDelay:1.0];
但有时您想自己创建和管理 NSTimer 对象,例如能够取消和重新使用计时器。
NSTask 用于运行另一个程序作为当前程序的子进程。这有点类似于启动一个单独的线程,但是如果一个子进程崩溃了,你的主程序会继续运行。程序之间的通信也与同一进程中多个线程之间的通信有很大不同。
你用“iphone”标记了你的问题,在 iPhone 上你永远不会使用 NSTasks。
NSOperations 当您需要处理大量不同的任务时使用,将它们放在队列中和/或在单独的线程中处理它们(尽管它们没有 在单独的线程中运行)。如果您的应用程序只需要创建几个专门的线程,那么就没有理由使用 NSOperation 类。但是,如果您将定期生成必须跟踪的任务(如与服务器通信),NSOperation 和 NSOperationQueue 将派上用场。
关于iphone - NSTimer、NSTask、NSThread 和 NSRunloop 之间的基本区别是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1124207/