我想了解一些关于GCD和线程的内容。
我的视图控制器中有一个for循环,要求我的模型做一些异步网络请求。
因此,如果循环运行5次,模型会发出5个网络请求。
说出我使用NSURLConnection的sendAsyncRequest并且将在另外5个线程上调用完成处理程序这一事实,我的模型已经创建了5个线程是否正确?
现在,如果我要求我的视图控制器在不同的线程和循环的每次迭代中执行for循环,那么对模型的调用应该依赖于前一次迭代,我是否会创建一个“Inception”线程在这里?
基本上,只有当前一个线程完全完成时,我才希望后续的异步请求到我的服务器(完全是指它的所有子线程也应该已经完成执行。)
我甚至无法正确地解决这个问题,因为我对自己感到非常困惑。 但如果有人可以提供任何帮助,那将会有所帮助。
答案 0 :(得分:13)
说明在一般情况下创建了五个线程是不正确的。
线程和块之间没有一对一的映射。 GCD是线程池的实现。
根据该设备的最佳设置创建一定数量的线程 - 在该OS版本下创建和维护线程的成本,可用的处理器核心数,已有的线程数但是目前被封锁以及Apple关注的任何其他因素可能都是相关的。
然后,GCD会将你的块传播到这些线程上。或者它可能会创建新线程。但它不一定。除此之外,队列只是建立块之间排序的方法。串行调度队列不一定拥有自己的线程。所有并发调度队列不一定拥有自己的线程。但是没有理由相信任何队列共享任何线程。
在操作系统版本之间,为块选择线程的确切方法已经发生了变化。例如。 iOS 4在线程创建方面非常挥霍,其中iOS 5+肯定没有。
GCD将尽力在这种情况下做最好的事情。不要浪费你的时间试图再次猜测它。
答案 1 :(得分:1)
"基本上,只有当前一个线程完全完成时,我才希望后续的异步请求到我的服务器(完全是指它的所有子线程也应该已经完成执行。)"
只关注上述陈述以避免混淆。简单的解决方案是创建一个队列。用5个循环提供队列。每个循环将同步发出网络请求(您可以使用NSURLConnection中可用的 sendSynchronousRequest:方法),在请求完成后执行操作,然后启动下一个循环。队列跟随FIFO将随后执行您的请求。
答案 2 :(得分:0)
GCD:将此视为可以接受任务的简单队列。任务是代码块。您可以在队列中输入任意数量的任务(允许系统限制)。队列有不同的风格。并发与串行。主要与全球。高优先级与低优先级。队列不是线程。
线程:它是依次执行代码的单行。您可以让多个线程同时处理您的代码。线程不是队列。
一旦你将两个实体分开,事情就会变得清晰起来。
GCD基本上使用进程中的线程来处理任务。在串行队列中,所有内容都按顺序处理。因此,您不需要在代码中使用同步机制,串行队列的本质可确保同步。如果这是并发队列(即同时处理2个或更多任务,则需要确保代码的关键部分受同步保护)。
以下是排队工作的方法。
dispatch_async(_yourDispatchQueue, ^() {
NSLog (@"work queued");
});
上面的NSLog现在将在不久的将来在后台线程中执行,但是在后台线程中。
如果您在我们发出请求时注意到我们使用dispatch_async。另一个变体是dispatch_sync。 2之间的不同之处在于您将请求放入队列后,异步变体将继续运行。同步变化不会!!
如果要使用GCD进行NSURLConnection,则需要注意启动连接的线程。这是SO链接以获取更多信息。 GCD with NSURLConnection