/*
一、 使用 GCD
先说下 block ,一般用于两个界面传值
@property (nonatomic,copy) void (^loggerBlock)(NSString *); //声明变量(也可以用typeDef)
在两个viewController中用block进行传值,这里不演示,只写出代码
__weak typeof(self) weakSelf = self;
传递信息
if (self.loggerBlock) {
self.loggerBlock(@"I am a block");
}
接受信息(下面的代码是放在另外一个VC中的)
ViewController *VC= [[ViewController alloc] init];
vc.loggerBlock = ^(NSString *txt){
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
label.text = txt;
[weakSelf.view addSubview:label];
};
*/
// 大多数的情况下,我们使用内联的方式来定义block,即将它的程序块写在调用的函数里面,例如:
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// code here...
});
// block 有如下的特点:
// 1.程序块可以在代码中以内联的方式来定义,如上
// 2.程序块可以访问在创建它的范围内的可用的变量,对block以外的变量进行修改操作要在变量前加前缀 __block 修饰
// 苹果官方文档:
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Blocks/Articles/bxVariables.html
// 二、 系统提供的 dispatch 方法
// 后台执行
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// do something
});
// 主线程执行
dispatch_async(dispatch_get_main_queue(), ^{
// do something
});
// 一次性执行:(直接输入 dispatch_once snippet 即可),一般的单例创建可以用这个实现
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// do something
});
// 延迟执行
//1. GCD自带
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// code to be executed after a specified delay, 此处是2.5秒后执行此处的代码
});
//2. 自定义
double delayInSecond = 2.5;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSecond *NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^{
// code to be executed after a specified delay, 此处是2.5秒后执行此处的代码
});
// 队列 dispatch_queue_t 也可以自己定义,比如:
// 一般队列
dispatch_queue_t My_QUEUE = dispatch_queue_create("this is my queue", NULL);
// 并行队列
dispatch_queue_t My_CONCURRENT_QUEUE = dispatch_queue_create("this is my CONCURRENT queue", DISPATCH_QUEUE_CONCURRENT);
// 串行队列
dispatch_queue_t My_SERIAL_QUEUE = dispatch_queue_create("this is my queue", DISPATCH_QUEUE_SERIAL);
// 异步执行队列
dispatch_async(My_QUEUE, ^{
// code here...
});
// 异步执行并发队列
dispatch_async(My_CONCURRENT_QUEUE, ^{
// code here...
});
// 异步执行串行队列
dispatch_async(My_SERIAL_QUEUE, ^{
// code here...
});
// GCD一些高级用法,例如让后台两个县城并行执行,然后等两个线程都结束后,再汇总执行结果,可用 dispatch_group、dispatch_group_async、dispatch_gruop_notify 来实现,如下:
dispatch_group_t group_t = dispatch_group_create(); // 创建组队列
dispatch_group_async(group_t, dispatch_get_global_queue(0, 0), ^{
// 并行执行的线程一
});
dispatch_group_async(group_t, dispatch_get_global_queue(0, 0), ^{
// 并行执行的线程二
});
dispatch_group_notify(group_t, dispatch_get_global_queue(0, 0), ^{
// 当线程一、二都执行完后,会调用这个block, 汇总结果
});
// 后台运行,使用block的另一个用处是可以让程序咋以后台较长久的运行,在以前,当应用被按Home键退出后,应用最多5秒钟的事件做一些保存或清理资源的工作,但是应用可以调用 UIApplication 的 beginBackgroundTaskWithExpirationHandler 方法,让应用最多有10分钟的事件在后台长久运行,这个时间可以用来做清理本地缓存工作,发送统计数据等工作。
// 让程序在后台长久运行的实例代码如下:
// AppDelegate.h 文件中
// @property (assign,nonatomic) UIBackgroundTaskIdentifier backgroundUpdateTask;
// AppDelegate.m 文件中
/*
- (void)applicationDidEnterBackground:(UIApplication *)application {
[self beginBackgruondUpdateTask];
}
-(void)beginBackgruondUpdateTask {
self.backgroundUpdateTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[self endBackgroundUpdateTask];
}];
}
-(void)endBackgroundUpdateTask {
[[UIApplication sharedApplication] endBackgroundTask:self.backgroundUpdateTask];
self.backgroundUpdateTask = UIBackgroundTaskInvalid;
}
*/
// 总结:GCD能极大地方便开发者进行多线程编程,尽量使用 GCD 来处理后台线程和 UI 线程的交互
文章借鉴了唐巧大神的《iOS开发进阶》,想看的同学点击下面的连接即可下载
PDF连接:http://pan.baidu.com/s/1o8RKaJw