为简化多线程应用的开发,IOS提供了GCD来实现多线程。它的核心就是队列与任务,任务在队列中始终以FIFO的顺序来处理。但由于任务的执行时间不同,因此先处理的任务不一定先结束。
使用GCD实现多线程只需遵守两个步骤即可:1.创建队列2.将任务提交给队列。队列分为串行队列与并行队列。当我们向队列中提交任务时就涉及到两种方式:异步提交任务(dispatch_async)、同步提交任务(dispatch_sync)。
一般而言,我们在说同步、异步的时候,特指那些需要其他部件协作或者需要一定时间完成的任务。
进程同步:就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。进程异步:当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者。 如果执行部件用状态来通知,那么调用者就需要每隔一定时间检查一次,效率就很低。如果是使用通知的方式,效率则很高,因为执行部件几乎不需要做额外的操作。至于回调函数,其实和通知没太多区别。
先看异步提交任务。创建一个单视图应用,向storyboard布局文件中添加一个按钮,button类型为自定义,为default、highlighted两种状态设置不同的titil及字体颜色。并未该button绑定concurrent方法(向并发队列异步提交任务)
#import "FKViewController.h"
@interface FKViewController ()
@end
@implementation FKViewController
// 定义2个队列
dispatch_queue_t serialQueue;
dispatch_queue_t concurrentQueue;
- (void)viewDidLoad
{
[super viewDidLoad];
// 创建串行队列
serialQueue = dispatch_queue_create("fkjava.queue", DISPATCH_QUEUE_SERIAL);
// 创建并发队列
concurrentQueue = dispatch_queue_create("fkjava.queue"
, DISPATCH_QUEUE_CONCURRENT);
}
- (IBAction)concurrent:(id)sender
{
// 依次将2个代码块提交给并发队列
// 两个代码块可以并发执行
dispatch_async(concurrentQueue, ^(void)
{
for (int i = 0 ; i < 100; i ++)
{
NSLog(@"%@=====%d" , [NSThread currentThread] , i);
}
});
dispatch_async(concurrentQueue, ^(void)
{
for (int i = 0 ; i < 100; i ++)
{
NSLog(@"%@------%d" , [NSThread currentThread] , i);
}
});
}
@end
运行程序后,我们会看到。两个block块中的代码是交替执行的,它们是并发的。button的在点击的同时迅速切换为高亮状态后又恢复为default状态。
再看同步提交任务。创建一个单视图应用,向storyboard布局文件中添加一个按钮,button类型为自定义,为default、highlighted两种状态设置不同的titil及字体颜色。并未该button绑定click方法(向全局并发队列同步提交任务)
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (IBAction)clicked:(id)sender
{
// 以同步方式先后提交2个代码块
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
, ^(void){
for (int i = 0 ; i < 100; i ++)
{
NSLog(@"%@=====%d" , [NSThread currentThread] , i);
[NSThread sleepForTimeInterval:0.1];
}
});
// 必须等第一次提交的代码块执行完成后,dispatch_sync()函数才会返回,
// 程序才会执行到这里,才能提交第二个代码块。
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
, ^(void){
for (int i = 0 ; i < 100; i ++)
{
NSLog(@"%@-----%d" , [NSThread currentThread] , i);
[NSThread sleepForTimeInterval:0.1];
}
});
}
@end
点击button程序运行,dispatch_sync函数先后两次提交代码块。从运行结果中看到,第一次提交代码块完成后才会执行第2次提交。整个过程中按钮一直处于高亮状态,知道第二个代码块执行完后,clicked方法才能返回,button回复到default状态。