1.NSThead
// 第一种方式
// 开辟线程需要消耗CPU的资源
// 先去需要一个入口函数,作为切入点
// 这种方式创建的线程需要手动执行
_thread = [[NSThread alloc] initWithTarget:self selector:@selector(doSemoThing) object:nil];
// 给线程设置名称
_thread.name = @"do semo thing thread";
// 执行线程
[_thread start];
// 第二种方式
// 自动执行
[NSThread detachNewThreadSelector:@selector(doSemoThing) toTarget:self withObject:nil];
// 第三种方式
// 自动执行
[self performSelectorInBackground:@selector(downloadImage) withObject:nil];
回主线程 ,通讯
[self performSelectorOnMainThread:@selector(reloadUI) withObject:nil waitUntilDone:NO];
// 在指定函数去执行某个方法
self performSelector:<#(SEL)#>
// 判断是否有取消的标识位
if ([_thread isCancelled]) {
// 退出当前线程
// 退出之后下面的代码就再执行,类似return
[NSThread exit];
}
// 睡秒1秒
sleep(1.0f);
// 微秒为单位
// usleep(<#useconds_t#>)
// 睡眠多久
[NSThread sleepForTimeInterval:1.0];
// 以当前时间为基准,向后偏移10秒
NSDate *date = [[NSDate date] dateByAddingTimeInterval:10.0f];
// 指定睡眠到什么时候
[NSThread sleepUntilDate:date];
2.GCD
Grand Central Dispatch 全局中央调度
GCD 是苹果以解决多核并发一种解决方案,能够自动帮我们管理线程(线程的创建,调度,销毁)
使用GCD两个重要的概念
任务 - 做什么(代码部分)
队列 - 管理任务,怎么做
任务分为两种
同步 - 需要等待上一个任务的完成,下面的任务才能执行
异步 - 不需要等待
区别 - 会不会阻塞线程
队列也分为两种
串行 - 一个一个地执行
并行 - 同时执行
// 核心概念:
// 任务:block
// 队列:把任务放到队列里面,队列先进先出的原则,
// 串行队列:顺序,一个一个执行(必须一个任务执行完了,才能从队列里面取出下一个任务)
// 并发队列:同时,同时执行很多个任务(可以同时取出很多个任务,只要有线程去执行)
// 同步sync:不会开新线程
// 异步async:会开新线程,多线程的代名词
// 串行队列同步执行:不开线程,在原来线程里面一个一个顺序执行
// 串行队列异步执行:开一条线程,在这个新线程里面一个一个顺序执行
// 并发队列异步执行:开多个线程,并发执行(不一定是一个一个)执行
// 并发队列同步执行:不开线程,在原来线程里面一个一个顺序执行
// 阶段性总结:
// 1. 开不开线程,由执行任务方法决定,同步不开线程,异步肯定开线程
// 2. 开多少线程,由队列决定,串行 最多 开一个线程, 并发可以开多个线程。 具体开多少个,有GCD底层决定,程序猿不能控制
// 获取主队列(串行)
dispatch_queue_t mainQueue = dispatch_get_main_queue();
// 创建一个队列
/**
创建一个新队列
参数1 队列的名字
参数2 队列的类型
DISPATCH_QUEUE_SERIAL 串行
DISPATCH_QUEUE_CONCURRENT 并行
*/
dispatch_queue_t newQueue = dispatch_queue_create("com.dispatch.newQueue", DISPATCH_QUEUE_SERIAL);
// 全局队列(并行),一般没有特定的要求,都使用全局队列
/**
参数1 优先级
DISPATCH_QUEUE_PRIORITY_DEFAULT 默认的
DISPATCH_QUEUE_PRIORITY_HIGH 优先级高
DISPATCH_QUEUE_PRIORITY_LOW 优先级低
DISPATCH_QUEUE_PRIORITY_BACKGROUND 最低的优先级
参数2
系统保留的参数0
*/
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
/**
串行队列:顺序,一个一个执行
同步任务:不会开辟新线程,是在当前线程执行
结果:不开新线程,在当前线程顺序执行
dispatch : 调度,GCD里面函数,都是以dispatch开头的
*/
- (void)gcdTest1
{
// 1. 创建一个串行队列
//参数:1. 队列标签 2. 队列的属性
dispatch_queue_t queue = dispatch_queue_create("itcast", DISPATCH_QUEUE_SERIAL);
NSLog(@"开始!!");
// 2. 同步执行任务
// 一般只要使用”同步“执行,串行队列对添加的同步任务,会立马执行
dispatch_sync(queue, ^{
NSLog(@"%@", [NSThread currentThread]);
});
NSLog(@"完成!!");
}
/**
串行队列:一个一个执行
异步执行:肯定会开新线程,在新线程执行
结果:只会开一个线程,而且所有任务都在这个新的线程里面执行
*/
- (void)gcdTest2
{
// 1. 串行队列
// 下面两种写法是一样的
// dispatch_queue_t queue = dispatch_queue_create(“itcast”, DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue = dispatch_queue_create(“itcast”, NULL);
// 创建全局队列。 全局队列是并行的、
dispatch_queue_t queue2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSLog(@"%@ %d", [NSThread currentThread]);
// 2. 异步执行
for (int i = 0; i < 10; i++) {
dispatch_async(queue, ^{
NSLog(@"%@ %d", [NSThread currentThread], i);
});
}
}
/**
并发队列:可以同时执行多个任务
异步执行:肯定会开新线程,在新线程执行
结果:会开很多个线程,同时执行
*/
- (void)gcdTest3
{
//1. 并行队列
dispatch_queue_t queue = dispatch_queue_create("cz", DISPATCH_QUEUE_CONCURRENT);
dispatch_queue_t queue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 2. 异步执行任务
for (int i = 0; i < 10; i++) {
dispatch_async(queue, ^{
NSLog(@"%@ %d", [NSThread currentThread], i);
});
}
}
/**
并发队列:可以同时执行多个任务
同步任务:不会开辟新线程,是在当前线程执行
结果:不开新线程,顺序一个一个执行。
*/
- (void)gcdTest4
{
//1. 并行队列
dispatch_queue_t queue = dispatch_queue_create("cz", DISPATCH_QUEUE_CONCURRENT);
// 2. 同步执行任务
for (int i = 0; i < 10; i++) {
dispatch_sync(queue, ^{
NSLog(@"%@ %d", [NSThread currentThread], i);
});
}
}
// 任务…
// 当组中所有的任务执行完后
// 通过我们设定好的通知告诉我们
dispatch_group_notify(group, queue, ^{
NSLog(@"执行完毕");
// 回到主线程刷新UI
dispatch_async(dispatch_get_main_queue(), ^{
self.view.backgroundColor = [UIColor redColor];
});
});
// 延迟执行。
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
});
3.NSOparetion
NSOperation是基于GCD封装的一套OC语言的队列间接管理线程的方式
NSOperation 三种类型
1.NSBlockOperation,以block为任务执行的操作
2.NSInvocationOperation,以SEL方法为任务的执行操作
3.NSOpertion 作为父类,创建子类的自定义任务,例子:AFNetworking 上的AFHTTPRequestOperation
NSOperation 比GCD增加
1.cancel 取消任务
2.addDependency 任务依赖
3.waitUntilAllOperationsAreFinished 等待任务完成
4.maxConcurrentOperationCount 最大并发数
NSOperation 官方推荐使用NSOperation处理事件大并发的情况
// NSOperation是一个抽象的父类,不要去直接使用
// 应该使用它的子类NSIvocationOperation,NSBlockOpreation
// 方式1
NSInvocationOperation *invocation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSemoThing) object:nil];
// 手动去执行
// [invocation start];
// 方式2
// 利用bolck的方式去创建线程
NSBlockOperation *block = [NSBlockOperation blockOperationWithBlock:^{
int i = 10;
while (i--) {
NSLog(@"block operation %d", i);
[NSThread sleepForTimeInterval:1.0];
}
}];
// 执行
// [block start];
// 创建队列,用来管理任务
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 设置队列的最大并发数
queue.maxConcurrentOperationCount = 5;
// 如果需要设置任务之间依赖关系,需要在添加到队列之前设置
// 前者依赖后者,只有后者执行完,前者才会取执行
[invocation addDependency:block];
// 将任务加入到队列中,队列会自动创建线程,并将队列中的任务取出放在线程中执行
[queue addOperation:invocation];
// 队列中的任务可以添加N个,队列会为每个任务创建一个线程
[queue addOperation:block];
// 如果有需要可以取消线程
// [invocation cancel];
// [block cancel];
// 取消队列中所有的线程
// [queue cancelAllOperations];