GCD笔记和问题汇总

来源:互联网 发布:node.js 开发web的优势 编辑:程序博客网 时间:2024/06/05 17:42

参考了不少博客,部分参考别人,附含一些自己的见解

参考博客:http://www.tuicool.com/articles/ZNn6Jz

1、GCD是我们iOS开发很重要的一些方法,它形式简单,但功能强大,但里面有很多又难以让人理解

比如进程和线程的区别?串行队列,和并行队列的区别?以及同步和异步的区别?get和post的区别?

dispatch_get_global_queue(0,0)和dispatch_get_main_queue(),还有dispatch_queue_create("test",NUll)这三种方法创建队列的区别?


2、GCD是用c语言写的函数,dispatch_queue_create(参数1,参数2);参数1是队列的名称,在调试时会有用,所以尽量不要用重名,第二个参数,我见过的有DISPATCH_QUEUE_SERIAL,这代表生存的队列是串行的,任务在单线程中执行,加载到此队列里面的任务会按先进先出的方式执行。

如果第二个参数是DISPATCH_QUEUE_CONCURRENT那么生存的队列是一个并发队列,里面的任务被分发到多个线程中去执行。

dispatch_get_global_queue(0,0)获得其实是一个并发队列

dispatch_get_main_queue()获得的其实是一个串行队列

为什么说这连个队列都不能用dispatch_resume()和dispatch_suspend()来控制队列的继续还是中断,解释原因是因为这是系统自动生存的。


3、接下来就是加载任务的同步和异步

dispatch_async(queue,^ {

});//异步执行block,函数立即返回

dispatch_sync(queue,^{

//block具体代码

});//同步执行block,函数一直等到block执行完毕才返回。

同步我们在使用中尽量少用,它是必须让queue执行完毕后才能执行里面的东西

4、在测试的过程中我发现这么一个问题
dispatch_sync(dispatch_get_main_queue(), ^{

          NSLog(@"同步3");

   });//单独写这么一个方法将之方到viewdidload里面执行,发现那句打印语句根本就不执行,但是如果我们将队列换成global或者换成一个新建的队列就执行里面的语句就能执行,我的理解是可能主线程队列还没有结束,必须等到他结束了才执行,而其他队列都不是主线程,相当于在另一个线程中运行。上面那里出现不打印相当于同步死锁一样,这是我的理解。


4、项目中常见的GCD模型

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^ {

                   //子线程中开始网络请求数据,全局队列执行

                dispatch_sync(dispatch_get_main_queue(),^{

               //主线程更新UI代码

                });

});//注意特征,前一个队列是全局队列,也是一个子线程,或者说后台执行;后一个队列是主线程


5、可以用串行队列实现一个锁的功能,比如多线程写同一个数据库,需要保持写入的顺序和每一个写入的完整性

dispatch_queue_t queue = dispatch_queue_create("com.dispatch.writedb",DISPATCH_QUEUE_SERIAL);//这是一个串行队列

- (void)writeDB:(NSData *data) {

         dispatch_sync(queue,^{

)};//同步必须等queue执行完毕再说


6、一些特别的dispatch方法

一次性执行

static dispatch_once_t onceToken;

dispatch_once(&onceToken,^{

    //代码执行的地方

});//这个在我们建单例的时候用到它。

延时执行

double delayInSeconds = 2.0;

dispatch_time_t poptime = dispatch_time (DISPATCH_TIME_NOW,delayInSeconds *NSEC_PER_SEC);

dispatch_after(portime,dispatch_get_main_queue(),^(void) {

//执行代码的地方

});


高级用法:让后台连个线程并行执行,然后等两个线程都结束后,再汇总执行结果,代码如下

dispatch_group_t group = dispatch_group_create();

dispatch_group_async(group,dispatch_get_global_queue(0,0),^{

     //并行执行的线程一

});

dispatch_group_async(group,dispatch_get_global_queue(0,0),^{

   //并行执行的线程二 

});

dispatch_group_notify(group,dispatch_get_global_queue(0,0),^{

   //合并结果

});//这个可以用在加载大型图片,太偏太大,如果我们仅仅开一个线程速度可能会慢,我们可以跟后台协商,将一张图片划分为几张图片,然后,分几个线程去下载,然后下载完成后,在合并图片(就是将一部分准确的放到屏幕上去)




0 0
原创粉丝点击