在 iOS 中其实目前有 4
套多线程方案:
- Pthreads:POSIX线程(POSIX threads),简称Pthreads,是线程的POSIX标准。该标准定义了创建和操纵线程的一整套API。
头文件:#import <pthread.h>
创建线程:
pthread_t thread;
pthread_create(&thread, NULL, start, NULL);
- NSThread: 它的生命周期还是需要手动管理,所以这套方案也是偶尔用用,比如
[NSThread currentThread]
,它可以获取当前线程类。
创建并启动:
// 实例方法创建 NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run:) object:nil]; // 启动 [thread start]; // 类方法创建 [NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:nil]; // NSObject方法 [self performSelectorInBackground:@selector(run:) withObject:nil];
- GCD (Grand Central Dispatch):它会自动管理线程的生命周期(创建线程、调度任务、销毁线程),由于使用了 Block(Swift里叫做闭包),使用更加方便灵活。
任务: GCD 中的Block代码
队列:用于存放任务。一共有两种队列, 串行队列 和 并行队列。
串行队列的任务,GCD 会 FIFO(先进先出)
地取出来一个,执行一个。
并行队列的任务,GCD 也会 FIFO
的取出来,但不同的是,它取出来一个就会放到别的线程,然后再取出来一个又放到另一个的线程。
主队列:
//获取主队列 dispatch_queue_t queue = dispatch_get_main_queue();
创建队列:
//串行队列: DISPATCH_QUEUE_SERIAL dispatch_queue_t queue = dispatch_queue_create("testQueue", NULL); dispatch_queue_t queue = dispatch_queue_create("testQueue", DISPATCH_QUEUE_SERIAL); //并行队列: DISPATCH_QUEUE_CONCURRENT dispatch_queue_t queue = dispatch_queue_create("testQueue", DISPATCH_QUEUE_CONCURRENT);
全局并行队列:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
创建任务:
// 同步任务 dispatch_sync(<#queue#>, ^{ //code here }); //异步任务 dispatch_async(<#queue#>, ^{ //code here });
- NSOperation & NSOperationQueue:
NSOperation 和 NSOperationQueue
分别对应 GCD 的任务 和 队列。
- 将要执行的任务封装到一个
NSOperation
对象中。 - 将此任务添加到一个
NSOperationQueue
对象中。
添加任务:
NSOperation
只是一个抽象类,所以不能封装任务。但它有 2 个子类用于封装任务。分别是:NSInvocationOperation
和 NSBlockOperation
。创建一个 Operation 后,需要调用 start
方法来启动任务,它会 默认在当前队列同步执行。中途取消一个任务,需要调用其 cancel
方法。
// 1.创建NSInvocationOperation对象 NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil]; // 2.开始执行 [invocationOperation start];
// 1.创建NSBlockOperation对象 NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"insert code"); }]; // 2.开始任务 [blockOperation start];
//1.创建NSBlockOperation对象 NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"insert code"); }]; //2.添加多个Block for (NSInteger i = 0; i < 5; i++) { [blockOperation addExecutionBlock:^{ NSLog(@"add %ld block:%@", i); }]; } //3.开始任务 [blockOperation start];
NOTE:addExecutionBlock
方法必须在 start()
方法之前执行,否则就会报错:
‘*** -[NSBlockOperation addExecutionBlock:]: blocks cannot be added after the operation has started executing or finished‘
创建队列:
主队列:
//OBJECTIVE-C NSOperationQueue *queue = [NSOperationQueue mainQueue];
自定义队列:
//1.创建一个队列 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; //2.创建NSBlockOperation对象 NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"insert code"); }]; //3.添加多个Block for (NSInteger i = 0; i < 3; i++) { [blockOperation addExecutionBlock:^{ NSLog(@"add %ld block", i); }]; } //4.队列添加任务 [queue addOperation: blockOperation];
// tast 1: NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"creat tast 1."); [NSThread sleepForTimeInterval:1.0]; }]; // tast 2: NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"creat tast 2."); [NSThread sleepForTimeInterval:1.0]; }]; // tast 3: NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{ NSLog(@"creat tast 3"); [NSThread sleepForTimeInterval:1.0]; }]; // 创建队列 NSOperationQueue *queue = [[NSOperationQueue alloc] init]; // 添加多个operations [queue addOperations:@[operation3, operation2, operation1] waitUntilFinished:NO];