Grand Central Diaptch (GCD) 多线程编程
来源:互联网 发布:联想移动硬盘加密软件 编辑:程序博客网 时间:2024/05/29 19:59
作者:舍得333 主页:http://blog.sina.com.cn/u/1509658847
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章原始出版、作者信息和本声明,否则将追究法律责任。
参考书籍: 《Objective-C高级编程 iOS与OS X多线程和内存管理》
书籍介绍连接:http://book.douban.com/subject/24720270/
1.
dispatch_async : 异步执行,意思就是,把参数里的block添加到queue后,函数就马上返回,继续执行下面的语句(不论该block是否执行完成。)
dispatch_sync : 同步执行,要把参数里的block添加到queue,要等待block执行完毕,函数才能返回执行下面的语句,否则,该线程就阻塞(卡死)在这条语句上(就像执行了sleep()一样)。所以,特别是在主线程上使用该方法要特别注意,block要执行很长时间的话,主线程就阻塞了。在其他线程也要注意,任何一个线程被阻塞都是很严重的问题。
2.这里分并行队列(concurrent dispatch queue)和串行队列(serial dispatch queue),这两个的区别不再赘述,请google。
2.1 队列的创建
dispatch_queue_t serialQueue = dispatch_queue_create("com.test.firstqueue", NULL);//串行队列
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.test.firstqueue", DISPATCH_QUEUE_CONCURRENT);//并行队列
dispatch_retain(serialQueue);
dispatch_release(serialQueue);
dispatch_release(serialQueue);
dispatch_release(concurrentQueue);
2.2 系统提供的标准queue
主要分为2个
Main dispatch queue //主线程的队列,属于串行
Global dispatch queue //子线程队列 ,属于并行队列
//Main dispatch queue 主线程的队列,属于串行
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
注意:对这两个线程执行 retain,release 不会有任何效果。
2.3 设置队列的优先级
队列的优先级 与 队列的类型(并行、串行)无关
注意:不可以对上面两个系统提供的queue 设置优先级,否则会产生不可预测的结果
我们一般只对自己create的queue设置优先级
create生成的队列 都与global queue的默认级别相同。
dispatch_queue_t subSerialQueue = dispatch_queue_create("com.test.setlevel", NULL);
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//设置第一个参数queue 与 第2个参数queue的优先级相同。注意,第一个queue ,不可以是系统提供的queue。
dispatch_set_target_queue(subSerialQueue, globalQueue);
小窍门:
有多个串行队列,这些队列之间内部执行是按照串行,但是queue之间是并行,
将这多个串行队列 的优先级 全都设置为 同一个串行队列,那么这个queue之间也就变成串行执行的,以为他们属于同一优先级,没法并行。
3.dispatch_after
// dispatch_after
- (void)dispatchAfter{
//在指定的时间后执行,即延迟**的时间执行
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, 3ull*NSEC_PER_SEC);
dispatch_after(delayTime, dispatch_get_main_queue(), ^(void){
NSLog(@"SW - dispatch_after");
});
//也可指定绝对时间执行,即指定某年某月某时执行
//在1970 年后的1024*1024秒后 的那个时间点执行
dispatch_time_t confirmTime = [self getDispatchTimeByDate:[NSDate dateWithTimeIntervalSince1970:(1024*1024)]];
dispatch_after(confirmTime, dispatch_get_main_queue(), ^(void){
NSLog(@"SW -dispatch_after confirmTime");
});
}
// 取得dispatch_time_t格式的绝对时间点
- (dispatch_time_t)getDispatchTimeByDate:(NSDate *)date{
NSTimeInterval interval;
double second,subSecond;
struct timespec time;
dispatch_time_t milestone;
interval = [date timeIntervalSince1970];
subSecond = modf(interval, &second);
time.tv_sec = second;
time.tv_nsec = subSecond *NSEC_PER_SEC;
milestone = dispatch_walltime(&time, 0);
return milestone;
}
4.dispatch_group
在你需要将一组block 执行之后,再追加一个结束处理的block。
在serial queue实现很简单,只需要把“结束block”添加的队列的最后即可。
但是在concurrent queue里面就很那实现,因为你无法确定什么时候所有的block执行完,这时就需要 dispatch_group
- (void)dispatchGroupNotify{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();//注意create出来的group,要release
//下面的添加的操作可以 不 在同一个queue内。
dispatch_group_async(group, queue, ^{ NSLog(@"outPrint_1");});
dispatch_group_async(group, queue, ^{ NSLog(@"outPrint_2");});
dispatch_group_async(group, queue, ^{ NSLog(@"outPrint_3");});
//当 添加到组group的所有block完成,那么在主线程调用该block输出。
dispatch_group_notify(group, dispatch_get_main_queue(), ^{ NSLog(@"group_finish");});
dispatch_release(group);
}
- (void)dispatchGroupWaitForever{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();//注意create出来的group,要release
//下面的添加的操作可以 不 在同一个queue内。
dispatch_group_async(group, queue, ^{ NSLog(@"outPrint_1");});
dispatch_group_async(group, queue, ^{ NSLog(@"outPrint_2");});
dispatch_group_async(group, queue, ^{ NSLog(@"outPrint_3");});
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
dispatch_release(group);
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章原始出版、作者信息和本声明,否则将追究法律责任。
参考书籍: 《Objective-C高级编程 iOS与OS X多线程和内存管理》
书籍介绍连接:http://book.douban.com/subject/24720270/
1.
dispatch_async : 异步执行,意思就是,把参数里的block添加到queue后,函数就马上返回,继续执行下面的语句(不论该block是否执行完成。)
dispatch_sync : 同步执行,要把参数里的block添加到queue,要等待block执行完毕,函数才能返回执行下面的语句,否则,该线程就阻塞(卡死)在这条语句上(就像执行了sleep()一样)。所以,特别是在主线程上使用该方法要特别注意,block要执行很长时间的话,主线程就阻塞了。在其他线程也要注意,任何一个线程被阻塞都是很严重的问题。
2.这里分并行队列(concurrent dispatch queue)和串行队列(serial dispatch queue),这两个的区别不再赘述,请google。
2.1 队列的创建
2.2 系统提供的标准queue
主要分为2个
Main dispatch queue //主线程的队列,属于串行
Global dispatch queue
//Main dispatch queue 主线程的队列,属于串行
注意:对这两个线程执行 retain,release 不会有任何效果。
2.3 设置队列的优先级
队列的优先级 与 队列的类型(并行、串行)无关
注意:不可以对上面两个系统提供的queue 设置优先级,否则会产生不可预测的结果
我们一般只对自己create的queue设置优先级
create生成的队列 都与global queue的默认级别相同。
小窍门:
有多个串行队列,这些队列之间内部执行是按照串行,但是queue之间是并行,
将这多个串行队列 的优先级 全都设置为 同一个串行队列,那么这个queue之间也就变成串行执行的,以为他们属于同一优先级,没法并行。
3.dispatch_after
// dispatch_after
- (void)dispatchAfter{
}
// 取得dispatch_time_t格式的绝对时间点
- (dispatch_time_t)getDispatchTimeByDate:(NSDate *)date{
}
4.dispatch_group
在你需要将一组block 执行之后,再追加一个结束处理的block。
在serial queue实现很简单,只需要把“结束block”添加的队列的最后即可。
但是在concurrent queue里面就很那实现,因为你无法确定什么时候所有的block执行完,这时就需要 dispatch_group
- (void)dispatchGroupNotify{
}
- (void)dispatchGroupWaitForever