趁着最近的项目不多的空档,将《Objective-C高级编程:iOS与OS X多线程和内存管理》这本业内大神推荐的书给阅读一遍,主要从底层解析ARC内存管理 Block 以及GCD,就GCD写一遍总结文章.
线程到底是什么?
int main()
{
id o = [myobject alloc] init];
[o execBlock];
return 0;
}
代码基本都是从上到下的顺序执行的,实际上这段代码会通过编译器转换成CPU命令列(二进制代码)
一个CPU只能执行一个命令,只能等这条命令执行完后再执行下一条,所以"一个CPU执行的CPU命令列为一天无分叉路径",即为线程,而一台计算机使用多个CPU就会有多条无分叉路径即为"多线程"
Dispatch Queue
dispatch_async(queue,^{
//想执行的任务
});
代码使用Block语法"定义想执行的任务",通过dispatch_async函数追加到赋值变量queue的"Dispatch Queue"中,这样就能使指定的Block在另一个线程中执行
添加任务的队列 Dispatch Queue分为两种:
Serial Dispatch Queue 等待现在执行中的处理结束
放在该队列中的两个任务A和B,在同一条线程中,先执行A时,只有等A执行完毕后才会执行B
dispatch_queue_t serialqueue = dispatch_queue_create("bunldid serialQueue",NULL);
Concurrent Dispatch Queue 不等待现在执行中的处理结束
放在改队列中的两人任务A和B,在执行A时不会等A执行完,会在另一条线程中执行
dispatch_queue_t concurrentlqueue = dispatch_queue_create("bunldid serialQueue",DISPATCH_QUEUE_CONCURRENT);
创建的全局队列就是系统提供的不等待执行的concurrent dispatch queue
dispatch_queue_t globalqueue = dispatch_get_global_queue(0,0);
全局队列存在优先级
dispatch_set_target_queue(用于手动设置队列执行的优先级)
dispatch_queue_t serialqueue = dispatch_queue_create("bunlad id", NULL);
dispatch_queue_t globalqueue = dispatch_queue_create("bulnd id",DISPATCH_QUEUE_CONCURRENT);
dispatch_set_target_queue(serialqueue, globalqueue);
这样serialqueue的优先级就高于globalqueue
dispatch_after(延时执行)
指定时间追加处理到Dispatch Queue
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW,3ull * NSEC_PER_SEC);
dispatch_after(time,dispatch_get_main_queue(),^{
//延时3秒执行
});
Dispatch Group
用于多个任务完成后再进行下下一个任务的操作
dispatch_queue_t queue = dispatch_get_blobal_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group,queue,^{ NSLog(@"balo1"); });
dispatch_group_async(group,queue,^{ NSLog(@"balo2"); });
dispatch_group_async(group,queue,^{ NSLog(@"balo2"); });
待三个任务完成后执行下面的任务
dispatch_group_notify(group,dispatch_get_main_queue(),^{
//最后执行的任务
});
dispatch_barrier_async
在访问数据库或文件时,使用Serial Dispatch Queue可避免数据竞争的问题,为了高效率的进行访问,读取处理时追加到Concurrent Dispatch Queue中进行,写入处理追加到Serial Dispatch Queue中进行处理
如果有多个concurrent dispatch queue进行多次的数据读取
只需要创建一个concurrent dispatch queue
dispatch_queue_t queue = dispatch_queue_create("bunld id",DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue,^{
//进行数据读取
});
dispatch_async(queue,^{
//进行数据读取
});
dispatch_async(queue,^{
//进行数据读取
});
当其中需要进行一部数据写入的操作时,可以使用Dispatch_barrier_async来进行操作,即使使用的不等待队列Concurrent Queue,仍然会等待这个任务完成后恢复不等待属性
dispatch_queue_t queue = dispatch_queue_create("bunld id",DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue,^{
//进行数据读取
});
dispatch_async(queue,^{
//进行数据读取
});
dispatch_barrier_async(queue,^{
//进行数据写入
});
dispatch_async(queue,^{
//进行数据读取
});
dispatch_apply
dispatch_apply函数是diapatch_sync函数和dispatch_group关联的API,这个函数是按照指定的次数将指定的Block追加到指定的Dispatch_Queue中,并等待全部执行结束后再执行下一步操作
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_apply(10,queue,^(size_t index) {
});
dispatch_apply函数中的参数:第一个是重复的次数,第二个是追加对象的Dispatch Queue,第三个带有Block参数的是重复追加的操作,可以用来代替for循环操作
以上就是这本书大概的对于GCD的介绍,不对之处,请多指教