第一,NSThread:一个NSThread对象就代表一条线程
1)创建与启动线程
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run)object:nil];
[thread start];
线程一启动,就会在线程thread中执行self的run方法.
2)主线程相关方法
+ (NSThread *)mainThread; // 获得主线程
- (BOOL)isMainThread; // 是否为主线程
+ (BOOL)isMainThread; // 是否为主线程
3)获得当前线程
NSThread *current = [NSThread currentThread];
4)创建线程后自动启动线程
[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
5)隐式创建并启动线程
[self performSelectorInBackground:@selector(run) withObject:nil];
6)控制线程状态
启动线程
- (void)start;// 进入就绪状态 -> 运行状态。当线程任务执行完毕,自动进入死亡状态
阻塞(暂停)线程
+ (void)sleepUntilDate:(NSDate *)date;
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
// 进入阻塞状态
强制停止线程
+ (void)exit;
// 进入死亡状态
注意:一旦线程停止(死亡)了,就不能再次开启任务.
[self performSelectorInBackground:@selector(download) withObject:nil];
在后台开启线程,进行下载任务.
[self performSelectorOnMainThread:@selector(downloadFinished:) withObject:imagewaitUntilDone:NO];
在完成下载任务后回到主线程,刷新UI(为了线程安全)
第二,GCD
dispatch_sync : 同步,不具备开启线程的能力
dispatch_async : 异步,具备开启线程的能力
并发队列 :多个任务可以同时执行
串行队列 :一个任务执行完后,再执行下一个任务
注意:队列影响的是执行方式,是多个任务同时执行还是多个任务串行执行.不影响要不要开线程
*获得全局的并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
*将 任务 添加 全局队列 中去 异步 执行
dispatch_async(queue, ^{// 执行耗时的异步操作...
});
dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
// 执行耗时的异步操作...
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主线程,执行UI刷新操作
});
});
*延时执行
调用NSObject的方法
[self performSelector:@selector(run) withObject:nil afterDelay:2.0];// 2秒后再用self的run方法
使用GCD函数
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 2秒后异步执行这里的代码...
});
*一次性代码
使用dispatch_once函数能保证某段代码在程序运行过程中只被执行1次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 只执行1次的代码(这里面默认是线程安全的)
});
*队列组
有这么1种需求:首先,分别异步执行2个耗时的操作.其次:等2个异步操作都执行完毕后,再回到主线程执行操作.
如果想要快速高效地实现上述需求,可以考虑用队列组
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 执行1个耗时的异步操作
});
dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 执行1个耗时的异步操作
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 等前面的异步操作都执行完毕后,回到主线程...
});
第三,NSOperationQueue
1)NSInvocationOperation
创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
创建操作
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download) object:nil];
注意:opertion 直接调用start,是同步执行(在当前线程执行操作)[operation start];
添加操作到队列中,会自动异步执行 [queue addOperation:operation];
2)NSBlockOperation
创建操作
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"---下载图片----11---%@", [NSThread currentThread]);
}];
添加操作到队列中(自动异步执行)
[queue addOperation:operation1];
注意:在调用start方法时,只有任务量大于1,才会开始异步执行 [operation start];
3)NSOperationQueue直接添加任务
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
// 执行1个耗时的异步操作
}
4)NSBlockOperation设置依赖
[operationB addDependency:operationA];
[operationC addDependency:operationB];
5)NSOperationQueue设置最大并发数
// 1.创建一个队列(非主队列)
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 2.设置最大并发(最多同时并发执行3个任务)
queue.maxConcurrentOperationCount = 3;