第15章 Grand Central Dispatch 和 后台处理
15.3 线程基础知识
一个进程中的所有线程共享可执行程序代码和全局数据。每个线程也可以以拥有一些独有的数据。
线程可以使用一种称为互斥量(mutex)或锁的特殊结构,这种结构可以确保特定的代码块无法一次被多个线程运行。在多个线程同时访问数据时,这有助于保证正确的结果,在一个线程更新某个值(在代码中称为临界区)时锁定其他线程。
要注意UIKit框架不是线程安全的,所有的UI处理都要放到主线程(main thread)中进行。
15.5 GCD:底层队列
GCD技术不仅仅适用于Objective-C,也适用于C和C++。他们可以在所有基于C的语言中使用。GCD的一个核心概念就是队列。系统提供了许多预定义的队列,包括可以保证始终在主线程上执行其工作的队列。它非常适合非线程安全的UIKit。
GCD能够访问一个线程池,该线程池可以在应用整个生命周期内重用。GCD会尽量维护一些适合机器体系结构的线程。在有工作需要处理时,他将自动利用更多的处理器核心,以充分利用更强大的机器性能。
15.5.1 傻瓜式操作
程序块可以分配给一个变量,以参数的形式传递给函数或方法,当然也可以执行。如:声明一个程序块:
//这个块没有参数也没有返回值
void (^loggerBlock)(void);
//将一个块赋值给上面声明的变量
loggerBlock = ^{
NSLog(……);
……
}
//执行这个块
loggerBlock();
Block块和函数指针非常像,但也有很多不同:
第一:程序块可以在代码内部以内联方式定义,也可以在代码块传递给另一个方法或函数时再次定义它。
第二:程序块可以访问在创建它的范围内所有可用的变量。默认情况下,程序块通过这种方式“捕获”了你访问的任何变量,将值复制到一个新的同名变量中,保留原始变量不变。OC对象会在复制时发送一个retain消息(Block块结束时,会发送release消息)。
可以在变量前添加__block来声明一个能够被块访问并修改的变量。
15.5.? dispatch_group_t、dispatch_group_async、dispatch_group_notify、dispatch_queue_t、dispatch_get_main_queue、dispatch_async等使用示例
-(void)practice
{
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(globalQueue, ^{
NSString *fetchResult = [self fetchSomethingFromServer];
NSString *processData = [self processData:fetchResult];
dispatch_group_t groupQueue = dispatch_group_create();
__block NSString *firstResult;
dispatch_group_async(groupQueue, globalQueue, ^{
firstResult = [self calculateFirstResult:processData];
});
__block NSString *secondResult;
dispatch_group_async(groupQueue, globalQueue, ^{
secondResult = [self calculateSecondResult:processData];
});
dispatch_group_notify(groupQueue, globalQueue, ^{
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"UI operate:%@",[NSString stringWithFormat:@"%@%@",firstResult,secondResult]);
});
});
});
}
15.6 后台处理
处理并发性的另一项功能是后台处理,后台处理支持在后台运行应用,在一切情形下甚至可以在用户按下主屏幕按钮后还可以在后台运行。后台处理功能意味着需要特定系统功能的应用可以在受限方式下继续运行。例如可以播放音频,或者拨打互联网电话的应用。
普通的应用在点击Home按键后都会进入挂起(suspended)状态(也可以通过Info.plst禁止此功能),应用即将被挂起时,它可以做的一件事是请求在后台运行一段时间(无论他是否属于可以再后台运行的特殊应用类型)。这样做是为了确保应用有足够的时间来关闭已经打开的文件、网络资源等。