我们运用多线程的目的是:将耗时的操作放在后台执行! 二、线程的状态与生命周期 下图是线程状态示意图,从图中可以看出线程的生命周期是:新建 - 就绪 - 运行 - 阻塞 - 死亡。 ? ...; 五、GCD的理解与使用 No.1:GCD的特点 GCD会自动利用更多的CPU内核 GCD自动管理线程的生命周期(创建线程,调度任务,销毁线程等) 程序员只需要告诉 GCD 想要如何执行什么任务...GCD总结:将任务(要在线程中执行的操作block)添加到队列(自己创建或使用全局并发队列),并且指定执行任务的方式(异步dispatch_async,同步dispatch_sync) No.3:队列的创建方法...主队列同步造成死锁的原因: 如果在主线程中运用主队列同步,也就是把任务放到了主线程的队列中。 而同步对于任务是立刻执行的,那么当把第一个任务放进主队列时,它就会立马执行。...主队列的创建如下,主队列上的任务是在主线程执行的。
如果不是添加到主队列上,异步会在子线程中执行任务 dispatch_queue_t queue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT...,与他相关的共有三个函数,分别是 dispatch_semaphore_create,dispatch_semaphore_signal,dispatch_semaphore_wait。...2、产生死锁的条件: 产生死锁的四个必要条件: (1) 互斥条件:一个资源每次只能被一个进程使用。 (2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。...同步对于任务是立刻执行的,那么当把任务放进主队列时,它就会立马执行,只有执行完这个任务,viewDidLoad才会继续向下执行。...而viewDidLoad和任务都是在主队列上的,由于队列的先进先出原则,任务又需等待viewDidLoad执行完毕后才能继续执行,viewDidLoad和这个任务就形成了相互循环等待,就造成了死锁。
在串行队列只开启一条线程 在并发队列开启多条线程 主队列 主队列是和主线程相关联的队列,主队列是GCD自带的一种特殊的串行队列,放在主队列中的任务,都会放到主线程中执行。...= dispatch_get_main_queue(); //把任务添加到主队列中执行 dispatch_async(queue, ^{ NSLog(@"使用异步函数执行主队列中的任务...1--%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"使用异步函数执行主队列中的任务2--%@",...[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"使用异步函数执行主队列中的任务3--%@",[NSThread...也就是说死锁的条件是因为dispatch_sync()方法在等待Block执行完毕,而Block在等待dispatch_sync()方法往下执行才能轮到它。
注意若你需要来自某个方法的数据,你必须内联另一个 Block 来找回它或考虑使用 dispatch_sync。 主队列(串行):这是在一个并发队列上完成任务后更新 UI 的共同选择。...以及,如果你在主队列调用 dispatch_async 到主队列,你能确保这个新任务将在当前方法完成后的某个时间执行。 并发队列:这是在后台执行非 UI 工作的共同选择。...自定义串行队列:在一个自定义串行队列上使用 dispatch_after 要小心。你最好坚持使用主队列。...主队列(串行):是使用 dispatch_after 的好选择;Xcode 提供了一个不错的自动完成模版。 并发队列:在并发队列上使用 dispatch_after 也要小心;你会这样做就比较罕见。...主队列(串行):与上面一样,在串行队列上不适合使用 dispatch_apply 。还是用普通的 for 循环吧。 并发队列:对于并发循环来说是很好选择,特别是当你需要追踪任务的进度时。
1、添加任务到队列(同步、异步): dispatch_sync: 同步添加,将指定的任务block同步追加到queue中,在追加的block结束之前,dispatch_sync会一直等待; 如果在主线程上执行同步任务...(任务也在主线程执行),会造成死锁: //会造成死锁 dispatch_sync(dispatch_get_main_queue(), ^{ // }); 但是在异步任务里可以用来切换到主线程 dispatch_async...主队列(main): dispatch_queue_t mainQ = dispatch_get_main_queue() 注意:不能sync向主队列提交任务,因为会造成死锁,只能async提交任务 全局队列...DISPATCH_TIME_NOW,150ull *NSEC_PER_MSEC),dispatch_get_main_queue(), ^{ //毫秒 }); 4、dispatch_group与dispatch_barrier...dispatch_async(queue, ^{NSLog(@"read");}); dispatch_async(queue, ^{NSLog(@"read");}); #可以保证写的时候只有这一个操作
是苹果公司为多核的并行运算提出的解决方案; GCD 会自动利用更多的CPU内核(比如双核、四核) GCD 会自动管理线程的生命周期(创建线程、调度任务、销毁线程) 总结:将任务添加到队列,并且指定执行任务的函数...通过dispatch_async(queue , {})获取; 不用等待当前语句执行完毕,就可以执行下一条语句 会开启线程,异步就是多线程的代名词; 1.3 GCD队列 主队列 通过dispatch_get_main_queue...2、GCD的使用 2.1 创建 同步函数 dispatch_sync(dispatch_get_main_queue();, ^{ }); 异步函数 dispatch_async(dispatch_get_main_queue...();, ^{ }); 主队列 dispatch_get_main_queue(); 全局并发队列 dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH...queue = dispatch_queue_create("HRTest", NULL); dispatch_sync(queue, ^{ dispatch_sync(queue
同步:你必须把我的代码执行完你再走,一定要执行完同步里的代码再执行下面的代码 void dispatch_sync(dispatch_queue_t queue, dispatch_block_t block...主队列: 遇到主队列,不管同步异步都要先执行完主线程里的代码再执行主队列里的代码 dispatch_sync方法不能在主队列中调用,因为这会无限期的阻止线程并会导致你的应用死锁。...主队列的特点:先执行完主线程上的代码,才会执行主队列中的任务 1、添加到主队列的任务只能由主线程来执行。 2、以先进先出的方式,只有当主线程的代码执行完毕后,主队列才会调度任务到主线程执行。...同步:你必须把我的代码执行完你再走,一定要执行完同步里的代码再执行下面的代码 void dispatch_sync(dispatch_queue_t queue, dispatch_block_t block...例子:将任务同步添加到队列和将任务异步添加到队列 (1)dispatch_sync(queue, task); (2)dispatch_async(dispatch_get_global_queue(0
并发队列:用来执行与UI无关的后台任务,dispatch_sync放在这里,方便等待任务完成进行后续处理或和dispatch barrier同步。dispatch groups放在这里也不错。...需要注意dispatch_barrier_async只在自己创建的队列上有这种作用,在全局并发队列和串行队列上,效果和dispatch_sync一样 //创建队列 self.isolationQueue...dispatch_async(GlobalMainQueue) { // 涉及到UI所以这个通知应该在主线程中,所以分派另一个异步任务到主队列中。...这里是指明在主队列中执行。...{ NSLog(@"1"); //3会等2,因为2在全局并行队列里,不需要等待3,这样2执行完回到主队列,3就开始执行 dispatch_sync(dispatch_get_global_queue
dispatch_group_enter就必定有一个dispatch_group_leave与之对应,否则可能会出现令你意想不到的崩溃。...直接替换成dispatch_async,效果一样。...它们都是在用dispatch_queue_create创建的并发队列上有效果,而在串行队列或者dispatch_get_global_queue创建的并发队列中,作用与dispatch_sync一致。...在串行队列或者dispatch_get_global_queue创建的并发队列中,dispatch_barrier_sync仅仅相当于dispatch_sync。...如果可以获取到说明当前上下文是在自己创建的queue中,如果不能获取到context data则表示当前是在其他队列上。 使用场景: 自己创建一个队列,然后保证所有的操作都在该队列上执行。
比如 int a = 1 或者 NSLog(@"log"); 执行任务有两种方式:同步执行(**dispatch_sync 与 异步执行(**dispatch_async**)**。...一些与 UI 无关的操作应该放到全局队列来执行,而不是主队列。比如网络请求这类操作。...同步与异步最大的区别就在于是否会阻塞当前线程: dispatch_sync 会阻塞当前线程。 dispatch_async 不会阻塞当前线程。...dispatch_apply 在各队列上的表现(当前为主线程): 主队列:死锁(毕竟这是同步执行); 串行队列:串行队列会完全抵消 dispatch_apply 并行迭代的功能,还不如 for 循环;...看看dispatch_barrier_sync 与 dispatch_sync 至于 dispatch_barrier_sync 与 dispatch_sync。
iOS多线程——RunLoop与GCD、AutoreleasePool GCD的使用姿势全解 经过前一篇文章的学习,可以发现直接使用NSThread来编写多线程程序有不少问题,线程在执行完成后就会退出,...(void); /* 获取主队列,即与主线程相关联的队列 如果需要提交任务到主线程使用该方法获取主线程的主队列即可 主队列是串行队列因为只维护主线程一个线程 */ dispatch_queue_t dispatch_get_main_queue...到此为止,四个实验都结束了,没有单独把主队列拿出来做实验,因为主队列本质还是一个串行队列,其实验结果和串行队列是一样的。...dispatch_barrier_async方法常与并发队列共用,前一段任务使用dispatch_async异步并发执行,然后插入一个dispatch_barrier_async执行一个中间任务,这个中间任务必须要等待前面的并发任务执行完成后才能开始执行...前文举的几个串行队列的栗子很多是不能使用主队列的,原因也正在此。
这是iOS 中几种多线程技术的关系。 介绍 GCD(Grand Central Dispatch)是OS X与iOS 开发中一种多核开发的解决方案。...iOS 中的串行队列有两种:主队列(dispatch_get_main_queue())、通过dispatch_queue_create创建的串行队列 1.1创建串行队列 主队列是系统为我们的应用创建的...,我们是没办法创建一个新的主队列的。...}); 3 总结 GCD的多线程使用都是同步/异步 与串行队列/并发队列组合使用的。...原因是ViewDidLoad是在主队列的主线程中执行,执行到dispatch_sync 时会阻塞住,等待dispatch_sync中的打印任务执行完毕。
任务是按顺序执行的(串行队列每次只有一个任务被执行,任务一个接一个按顺序执行)。 下边讲讲刚才我们提到过的特殊队列:主队列。...主队列:GCD自带的一种特殊的串行队列 所有放在主队列中的任务,都会放到主线程中执行 可使用dispatch_get_main_queue()获得主队列 我们再来看看主队列的两种组合方式。...: 所有任务都是在主线程(非当前线程)中执行的,没有开启新的线程(所有放在主队列中的任务,都会放到主线程中执行)。...syncMain 任务在其他线程中执行到追加任务1到主队列中,因为主队列现在没有正在执行的任务,所以,会直接执行主队列的任务1,等任务1执行完毕,再接着执行任务2、任务3。所以这里不会卡住线程。...: 所有任务都是在当前线程(主线程)中执行的,并没有开启新的线程(虽然异步执行具备开启线程的能力,但因为是主队列,所以所有任务都在主线程中)。
(跟主线程相关联的队列) 主队列是GCD自带的一种特殊的串行队列,放在主队列中的任务,都会放到主线程中执行 //1.获得主队列 dispatch_queue_t queue = dispatch_get_main_queue...}); 同步函数+主队列:死锁 //1.获得主队列 dispatch_queue_t queue = dispatch_get_main_queue(); //2.同步函数 dispatch_sync...使用同步或异步函数,传入主队列即可。...4.2 NSOperationQueue的使用 NSOperation中的两种队列 主队列:通过mainQueue获得,凡是放到主队列中的任务都将在主线程执行 非主队列:直接alloc init出来的队列...立刻就会执行block块中的代码 // block中的代码与op1不一定在一个线程中执行,但是一定在子线程中执行 op1.completionBlock = ^{ NSLog(@"op1
串行与并行 在使用GCD的时候,我们会把需要处理的任务放到Block中,然后将任务追加到相应的队列里面,这个队列,叫做Dispatch Queue。...举一个简单的例子,在三个任务中输出1、2、3,串行队列输出是有序的1、2、3,但是并行队列的先后顺序就不一定了。 同步与异步 串行与并行针对的是队列,而同步与异步,针对的则是线程。...表示是一个同步线程; dispatch_get_main_queue表示运行在主线程中的主队列; 任务2是同步线程的任务。...从dispatch_get_global_queue可以看出,任务2被加入到了全局的并行队列中,当并行队列执行完任务2以后,返回到主队列,继续执行任务3。...Demo5 dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"1"); // 任务1 dispatch_sync(
我们GCD使用常伴有dispatch_sync和dispatch_async,这就是同步执行和异步执行。 同步和异步 同步执行:任务都在当前线程中执行,执行过程中会阻塞当前线程。...这也验证了 串行队列同步执行:任务都在当前线程执行(同步),并且顺序执行(串行) 这里需要注意的是代码直接在viewDidLoad里写的,主队列也是一个串行队列,但在主线程中使用主队列同步执行会造成死锁...,若是直接在主队列异步调用,任务执行都在主线程上。...("concurrentQueue", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ NSLog(@"task1");...NSLog(@"task2"); NSLog(@"task2---%@",[NSThread currentThread]); }); dispatch_async
) dispatch_async(queue, block); 1.3 GCD 执行任务的方式 1.3.1 同步 dispatch_sync 提交一个 block 对象到指定队列以同步执行...,block会被自动copy与release; * 该block没有返回值,也没有参数; * 此参数不能为空(NULL) */ void dispatch_sync(dispatch_queue_t...如在主队列异步执行,不会开启新线程,因为主队列的任务在主线程上执行) 1.4 GCD 的队列 1.4.1 GCD 队列介绍 Dispatch Queue: 一个用于管理主线程或子线程上串行或并发执行的任务的对象...主队列(dispatch_queue_main_t) 主队列是一种特殊的串行队列,它特殊在与主线程关联,主队列的任务都在主线程上执行,主队列在程序一开始就被系统创建并与主线程关联。...示例1: /* 队列的特点:FIFO (First In First Out) 先进先出 以下将 block(任务2)提交到主队列,主队列将来要取出这个任务放到主线程执行。
(可以开启多个线程,并且同时执行任务) 注意:并发队列的并发功能只有在异步(dispatch_async)函数下才有效 两者具体区别如下两图所示。 3....所有放在主队列中的任务,都会放到主线程中执行。 可使用dispatch_get_main_queue()获得主队列。...; 3.2 任务的创建方法 GCD 提供了同步执行任务的创建方法dispatch_sync和异步执行任务创建方法dispatch_async。...// 同步执行任务创建方法 dispatch_sync(queue, ^{ // 这里放同步执行任务代码 }); // 异步执行任务创建方法 dispatch_async(queue, ^{...5.同步执行 + 主队列 6.异步执行 + 主队列 那么这几种不同组合方式各有什么区别呢,这里为了方便,先上结果,再来讲解。你可以直接查看表格结果,然后跳过 4. GCD的基本使用 。
所有放在主队列中的任务,都会放到主线程中执行。 可使用dispatch_get_main_queue()获得主队列。...; 3.2 任务的创建方法 GCD 提供了同步执行任务的创建方法dispatch_sync和异步执行任务创建方法dispatch_async。...// 同步执行任务创建方法 dispatch_sync(queue, ^{ // 这里放同步执行任务代码 }); // 异步执行任务创建方法 dispatch_async(queue, ^{...主队列:GCD自带的一种特殊的串行队列 所有放在主队列中的任务,都会放到主线程中执行 可使用dispatch_get_main_queue()获得主队列 我们再来看看主队列的两种组合方式。...syncMain 任务在其他线程中执行到追加任务1到主队列中,因为主队列现在没有正在执行的任务,所以,会直接执行主队列的任务1,等任务1执行完毕,再接着执行任务2、任务3。所以这里不会卡住线程。
// 串行队列的创建方法 2. 任务的创建方法 GCD 提供了同步执行任务的创建方法 dispatch_sync 和异步执行任务创建方法 dispatch_async。...// 同步执行任务创建方法 dispatch_sync(queue, ^{ // 这里放同步执行任务代码 }); // 异步执行任务创建方法 dispatch_async(queue, ^{...// 这里放异步执行任务代码 }); 虽然使用 GCD 只需两步,但是既然我们有两种队列(串行队列 / 并发队列),两种任务执行方式(同步执行 / 异步执行),如果当前代码默认放在主队列中,我们也有两种特殊的组合方式...这四种不同的组合方式是: 同步执行 + 并发队列 异步执行 + 并发队列 同步执行 + 串行队列 异步执行 + 串行队列 同步执行 + 主队列 异步执行 + 主队列 我们先来考虑最基本的使用,也就是当前线程为...『主线程』中,『不同队列』+『不同任务』简单组合的区别: 任务 并发队列 串行队列 主队列 同步(sync) 没有开启新线程,串行执行任务 没有开启新线程,串行执行任务 死锁卡住不执行 异步(async
领取专属 10元无门槛券
手把手带您无忧上云