dub*_*eat 10 cocoa multithreading
我正在努力学习线程,我很困惑.我确信所有的答案都在苹果文档中,但我发现很难分解和消化.也许有人可以为我清除一件事或两件事.
1)performSelectorOnMainThread
上面只是在主运行循环中注册一个事件,或者它是否以某种方式成为新线程,即使该方法显示"mainThread"?如果线程的目的是减轻主线程的处理,这有什么帮助?
2)RunLoops
如果我想创建一个完全独立的线程,我使用"detachNewThreadSelector"是真的吗?调用start on this会为已创建的线程启动默认运行循环吗?如果是这样,运行循环进入哪里?
3)最后,我看到了使用NSOperationQueue的例子.是不是说如果使用performSelectorOnMainThread,那么线程仍在队列中,所以不需要NSOperation?
4)我应该忘记所有这些而只是使用Grand Central Dispatch吗?
Yuj*_*uji 26
运行循环
您可以将Run Loop视为与线程关联的for循环事件处理.这是由系统为每个线程提供的,但它只对主线程自动运行.
请注意,运行运行循环和执行线程是两个不同的概念.当您只是执行长计算而不必响应各种事件时,您可以在不运行运行循环的情况下执行线程.如果要响应辅助线程中的各种事件,则检索与该线程关联的运行循环
[NSRunLoop currentRunLoop]
Run Code Online (Sandbox Code Playgroud)
并运行它.运行循环可以处理的事件称为输入源.您可以将输入源添加到运行循环中.
PerformSelector
performSelectorOnMainThread:将目标和选择器添加到名为performSelector输入源的特殊输入源.主线程的运行循环使输入源出列并逐个处理方法调用,作为其事件处理循环的一部分.
的NSOperation/NSOperationQueue
我认为NSOperation这是一种在应用程序中显式声明各种任务的方法,这需要一些时间,但可以大部分独立运行.它比使用自己分离新线程和自己维护各种东西更容易.main NSOperationQueue自动维护一组重用的后台线程,NSOperations并行并行运行.所以,是的,如果你只需要在主线程中排队操作,你可以取消NSOperationQueue并使用performSelectorOnMainThread:,但这不是主要观点NSOperation.
GCD
GCD是Snow Leopard中引入的新基础设施.NSOperationQueue现在已经实现了它.它适用于功能/块级别.提供块dispatch_async非常方便,但对于我喜欢使用的大块操作NSOperation,尤其是当应用程序中的各个位置使用该块时.
摘要
你需要阅读官方Apple Doc!关于这一点,还有很多信息丰富的博客文章.
1)performSelectorOnMainThread
以上只是在主运行循环中注册一个事件......
你问的是实施细节.不要担心它是如何工作的.
它的作用是在主线程上执行该选择器.
...或者它是某种新线程,即使该方法说"mainThread"?
没有.
如果线程的目的是减轻主线程的处理,这有什么帮助?
当您需要在主线程上执行某些操作时,它可以帮助您.一个常见的例子是更新您的UI,您应该始终在主线程上执行此操作.
还有其他方法可以在新的辅助线程上执行操作,尽管NSOperationQueue和GCD通常更容易实现.
2)RunLoops
如果我想创建一个完全独立的线程,我使用"detachNewThreadSelector"是真的吗?
这与run循环无关.
是的,这是启动新线程的一种方法.
调用start on this会为已创建的线程启动默认运行循环吗?
没有.
start无论如何,我不知道你在这里"拜访"了什么.detachNewThreadSelector:不返回任何东西,它立即启动线程.我认为你把它与NSOperations混为一谈(你也不会自己开始 - 这就是队列的工作).
如果是这样,运行循环进入哪里?
运行循环只存在,每个线程一个.在实施方面,他们可能会根据需求懒散地创建.
3)最后,我看到了使用NSOperationQueue的例子.是不是说如果使用performSelectorOnMainThread,那么线程仍在队列中,所以不需要NSOperation?
这两件事是无关的.
performSelectorOnMainThread:确切地说:在主线程上执行选择器.
NSOperations在辅助线程上运行,每个操作一个.
操作队列确定操作(及其线程)的启动顺序.
线程本身没有排队(除了可能由调度程序,但这是内核的一部分,而不是您的应用程序).操作排队,并按顺序启动.一旦启动,它们的线程并行运行.
4)我应该忘记所有这些而只是使用Grand Central Dispatch吗?
GCD或多或少与操作队列相同.只要你不理解另一个,你就不会理解.
在一个线程中,一种安排事情发生的方法.有些可能会安排在特定的日期(计时器),有些则只是"每当你到处"时(来源).其中大部分在空闲时都是零成本,只在事情发生时消耗任何CPU时间(定时器触发或发出信号源),这使得运行循环成为一种非常有效的方式,可以在没有任何线程的情况下同时进行多项操作.
创建计划的计时器时,通常不会自己处理运行循环; 计时器为您自动添加到运行循环中.
线程允许在不同的处理器上同时发生多个事情.事物1可以发生在线程A(在处理器1上),而事物2发生在线程B上(在处理器0上).
这可能是个问题.多线程编程是一种舞蹈,当两个线程试图进入同一个地方时,就会产生痛苦.这称为争用,大多数关于线程编程的讨论都是关于如何避免它的主题.
你有一件事需要做.那是一个操作.你不能在主线程上完成它,或者你只是像正常一样发送消息 ; 你需要在后台运行它,在辅助线程上运行它.
要实现这一点,请将其表示为NSOperation对象(您创建NSOperation的子类并实例化它)或块(或两者),然后将其添加到NSOperationQueue(NSOperations,包括NSBlockOperation)或调度队列(裸块) ).
GCD也可用于在主线程上发生事情; 您可以创建串行队列并向其添加块.顾名思义,串行队列一次只运行一个块,而不是并行运行一堆.
我不建议直接创建线程.使用NSOperationQueue或GCD代替; 它们会迫使您进入更好的思维习惯,从而降低线程代码引发头痛的风险.
对于定期运行的东西,不适合NSOperations和GCD块的"我需要做的事情"模型,考虑只在主线程上使用运行循环.有可能,毕竟你不需要把它放在一个线程上.例如,3D游戏中的渲染循环可以是简单的计时器.