pThead:
pThread是一套很多操作系统上都用到的API, 所以移植性特别强, 同样适用于iOS, 但是使用的比较少.
使用:
首先在需要使用pthread的文件中导入头文件
#import <pthread.h>
创建:
第一个参数: pthread指针
第二个参数: 设置为NULL
第三个参数: 一个函数指针, 相当于selector
第四个参数: 设置为NULL
NSThread:
NSThread经过苹果公司封装后的, 完全面向对象的, 可以直接对线程对象进行操作.
创建: 三种方式
1.
NSThread *thread = [[NSThread alloc]initWith Target:self selector:@selector(runThread) object:nil];
[threadstart];
2.
[NSThread detachNewThreadSelector:@selector(runThread)to Target:self withObject:nil];
3.
[self performSelectorInBackground:@selector(runThread) withObject:self];
注:
有些时候如售票, 发单等情况(需要计算数量) 要使用线程锁, 开启NSThread锁有两种方式
1.
@synchronized(self) {
<#statements#>
}
2.
@property (nonatomic,strong) NSCondition *condition;
[self.condition lock]; //锁
[self.condition unlock]; //解锁
GCD:
GCD是苹果为了多核的并行运算提出的一套解决方案, 它可以合理地更多地利用CPU内核,最重要的是它可以自动管理线程的生命周期,比如创建线程, 任务调度, 销毁线程,我们只需要告诉GCD要做的事情就可以了,它也是基于C语言的,不过里边引入了block(OC).
划分:
同步&异步 (以当前线程会不会被阻塞划分)
同步在任务执行时会阻塞当前线程,在任务执行完毕后才会执行其他任务. 而异步则不会
串行&并行 (队列相关的, 对有依赖关系的任务非常重要)
常用:
dispatch_get_main_queue : 主线程的队列, 回到主线程, 执行刷新UI等操作
dispatch_get_global_queue : 全局的并行队列
第一个参数可以设置线程在并行队列中的优先级, 共有以下几种, 优先级由高到低为: HIGH > DEFAULT > LOW
在并行队列中这种设置优先级的方式只可以影响到线程先后的执行顺序, 并不能决定线程是否可以先执行完毕.
创建方式:
创建并行队列:
dispatch_async(dispatch_get_global_queue(0,0), ^{
//耗时操作
[NSThread sleepForTimeInterval:3];
dispatch_async(dispatch_get_main_queue(), ^{
//刷新UI
});
});
dispatch_queue_t queue =dispatch_queue_create("test",DISPATCH_QUEUE_CONCURRENT);
创建串行队列:
dispatch_queue_t queue =dispatch_queue_create("test",DISPATCH_QUEUE_SERIAL); //第二个参数也可以传NULL
dispatch_group_t:
使用场景:在多个任务异步处理之后, 需要一个统一的回调通知告诉我们所有的任务都结束了, 然后根据需求处理其他任务, 回调通知如下:
dispatch_queue_t queue =dispatch_queue_create("test",DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group =dispatch_group_create();
dispatch_group_async(group, queue, ^{
NSLog(@"test 1");
[NSThread sleepForTimeInterval:2];
NSLog(@"test 1 end");
});
dispatch_group_async(group, queue, ^{
NSLog(@"test 2");
[NSThread sleepForTimeInterval:2];
NSLog(@"test 2 end");
});
dispatch_group_async(group, queue, ^{
NSLog(@"test 3");
[NSThread sleepForTimeInterval:2];
NSLog(@"test 3 end");
});
dispatch_group_notify(group, queue, ^{
NSLog(@"tasks over");
});
dispatch_group_t group =dispatch_group_create();
dispatch_group_async(group, queue, ^{
NSLog(@"test 1");
[NSThread sleepForTimeInterval:2];
NSLog(@"test 1 end");
});
控制台打印结果:
注:
当我们要在dispatch_group_async中执行的耗时操作(比如网络请求回调)执行的应该是同步操作,不应该是异步操作, 如果要进行异步操作,可以按如下步骤做:
dispatch_group_enter(group);
[self sendRequest:^{
NSLog(@"1");
dispatch_group_leave(group);
}];
enter要与leave成对出现!
GCD其他:
dispatch_once的使用:
单例:
只执行一次的操作:
如某个按钮只允许点击一次等.
dispatch_after:
延迟执行:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2*NSEC_PER_SEC)),dispatch_get_main_queue(), ^{
//延迟操作
});
NSOperation:
NSOperation实际上是对GCD的一种封装,它的实例封装了需要执行的操作以及执行操作所需要的数据,并且能够以并发或者非并发执行操作, NSOperation是一个抽象类, 我们需要使用它的子类, 有两种使用方式:
1.NSInvocationOperation & NSBlockOperation
2.自定义类集成NSOperation
相关概念:
1. NSOperationQueue(线程池)
a. addOperation
b. setMaxConcurrentOperationCount
2. 状态
ready(执行之前, 只有当状态为ready时才能进行操作), cancelled(取消,当执行任务时可以进行取消的, 如果任务正在执行,取消无效,直到任务执行完毕), executing(正在执行), finished(执行结束), asynchronous(是否是并发).
3. 依赖-addDependency
依赖关系不能相互依赖或者循环依赖, 否则会造成死锁.
NSInvocationOperation, NSBlockOperation 通常与 NSOperationQueue一起使用以达到线程异步
例:
@property(nonatomic,strong) NSOperationQueue *queue;