GCD/Block
来源:互联网 发布:win10网络连接不上 编辑:程序博客网 时间:2024/06/05 02:56
GCD
唐巧的博客
block 的定义
block 的定义有点象函数指针,差别是用 ^ 替代了函数指针的 * 号,如下所示:
// 申明变量(void) (^loggerBlock)(void);// 定义loggerBlock = ^{ NSLog(@"Hello world");};// 调用loggerBlock();
但是大多数时候,我们通常使用内联的方式来定义 block,即将它的程序块写在调用的函数里面,例如这样:
dispatch_async(dispatch_get_global_queue(0, 0), ^{ // something});
从上面大家可以看出,block 有如下特点:
- 程序块可以在代码中以内联的方式来定义。
- 程序块可以访问在创建它的范围内的可用的变量。
系统提供的 dispatch 方法
为了方便地使用 GCD,苹果提供了一些方法方便我们将 block 放在主线程 或 后台线程执行,或者延后执行。使用的例子如下:
// 后台执行:dispatch_async(dispatch_get_global_queue(0, 0), ^{ // something});// 主线程执行:dispatch_async(dispatch_get_main_queue(), ^{ // something});// 一次性执行:static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{ // code to be executed once});// 延迟 2 秒执行:double delayInSeconds = 2.0;dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ // code to be executed on the main queue after delay});
dispatch_queue_t
也可以自己定义,如要要自定义 queue
,可以用 dispatch_queue_create
方法,示例如下:
dispatch_queue_t urls_queue = dispatch_queue_create("blog.devtang.com", NULL);dispatch_async(urls_queue, ^{ // your code});dispatch_release(urls_queue);
另外,GCD 还有一些高级用法,例如让后台 2 个线程并行执行,然后等 2 个线程都结束后,再汇总执行结果。这个可以用 dispatch_group, dispatch_group_async 和 dispatch_group_notify 来实现,示例如下:
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), ^{ // 汇总结果});
修改 block 之外的变量
默认情况下,在程序块中访问的外部变量是复制过去的,即写操作不对原变量生效。但是你可以加上 __block 来让其写操作生效,示例代码如下:
__block int a = 0;void (^foo)(void) = ^{ a = 1;}foo();// 这里,a 的值被修改为 1
后台运行
使用 block 的另一个用处是可以让程序在后台较长久的运行。在以前,当 app 被按 home 键退出后,app 仅有最多 5 秒钟的时候做一些保存或清理资源的工作。但是应用可以调用 UIApplication
的beginBackgroundTaskWithExpirationHandler
方法,让 app 最多有 10 分钟的时间在后台长久运行。这个时间可以用来做清理本地缓存,发送统计数据等工作。
让程序在后台长久运行的示例代码如下:
// AppDelegate.h 文件@property (assign, nonatomic) UIBackgroundTaskIdentifier backgroundUpdateTask;// AppDelegate.m 文件- (void)applicationDidEnterBackground:(UIApplication *)application{ [self beingBackgroundUpdateTask]; // 在这里加上你需要长久运行的代码 [self endBackgroundUpdateTask];}- (void)beingBackgroundUpdateTask{ self.backgroundUpdateTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ [self endBackgroundUpdateTask]; }];}- (void)endBackgroundUpdateTask{ [[UIApplication sharedApplication] endBackgroundTask: self.backgroundUpdateTask]; self.backgroundUpdateTask = UIBackgroundTaskInvalid;}
0 0
- GCD Block
- GCD/Block
- 初识GCD和block
- gcd block讲解
- Block and GCD
- GCD和Block 使用
- GCD code block
- gcd,block,dispatch queue
- 6. GCD Block
- block 与 gcd
- GCD block(一)
- GCD block(一)
- 【读书笔记】iOS-GCD-block
- GCD和Block
- Block和GCD介绍
- GCD简介以及block
- gcd使用block注意事项
- OC Block,ARC,GCD
- 基于cocos2d-lua的shader入门玩转
- Spark中遇到的一些问题和相应的解决办法
- Linux ROS与嵌入式的串口通信
- 运行ORB-SLAM笔记_编译篇(一)
- 运行ORB-SLAM笔记_使用篇(二)
- GCD/Block
- 相机标定 matlab opencv ROS三种方法标定步骤(1)
- Android
- 相机标定 matlab opencv ROS三种方法标定步骤(3)
- Eclipse linux 环境变量不起作用/旧环境变量始终生效
- 相机标定 matlab opencv ROS三种方法标定步骤(2)
- 5.Django入门:教程-视图和模板
- 编译 ORB_SLAM2 (一)
- 图像处理_imgproc笔记(1)