新开多线程:
(普通)
// GCD 是基于队列的 多线程实现方式
// 队列的类型
// 1.并行: 多个任务同时执行 Concurrent
// 2.串行: 依次执行任务(同一事件只执行一个任务) Serial
// 自己创建一个队列
// 参数1:给队列起个名字
// 参数2:选择队列的类型 DISPATCH_QUEUE_CONCURRENT(串行)
dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
// 使用队列
// 参数1: 在哪个队列执行代码
// 参数2: 要执行的代码
dispatch_async(queue, ^{
[self downLoadImage]; //回调
});
(高级用法)
// 系统定义了5个队列
// 1. 一个串行队列 主队列作用 : 管理主线程的相关事务
// 获得主队列
dispatch_queue_t mainQueue = dispatch_get_main_queue();
// 在主队列执行任务
// dispatch_async(mainQueue, ^{
// [self btnUpClicked:nil];
// });
// 2. 4个并行队列 (并行队列)
// 参数1: 选择队列的优先级
// 参数2: 给未来使用 一般填0
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// dispatch_async(globalQueue, ^{
// [self btnUpClicked:nil];
// });
// 高端使用
// 1.全局队列获取数据 回到主队列将数据加载到视图上
// dispatch_async(globalQueue, ^{
//
// // 全局队列(子线程)获取数据
// NSString *str = @"htt://www.baidu.com";
// NSURL *url = [NSURL URLWithString:str];
//
// NSData *data = [NSData dataWithContentsOfURL:url];
// UIImage *image = [UIImage imageWithData:data];
//
// // 返回主线程 加载UI/更新UI
// dispatch_async(mainQueue, ^{
//
// UIImageView *imageView = [[UIImageView alloc] init];
// // 给视图赋值
// imageView.image = image;
//
// });
// });
// 2.一段代码只执行依次
// 大部分的时候 都在单例方法中使用
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"只执行依次");
});
// 3.一段代码执行多次 (全局队列有效)
// 参数1: 执行多少次
// 参数2: 在哪个队列有效
// 参数3: 要执行的内容
dispatch_apply(4, globalQueue, ^(size_t a) {
NSLog(@"%zu", a);
});
// 4.定时
// 参数1: 间隔几秒
// 参数2: 执行的内容
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(44 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"=====");
});
学习
#pragma mark -- 开辟线程
//一、NSObject 隐式开辟线程
//开辟后台线程 执行某方法
// [self performSelectorInBackground:@selector(loadingImageWithUrlString:) withObject:IMAGE_URL];
//会到主线程中做某事
// [self performSelectorOnMainThread:<#(nonnull SEL)#> withObject:<#(nullable id)#> waitUntilDone:<#(BOOL)#>]
//二、 NSThread 线程类 对pthread的一种封装
// [NSThread detachNewThreadSelector:@selector(loadingImageWithUrlString:) toTarget:self withObject:IMAGE_URL];
//对象方法 需要手动管理
// NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(loadingImageWithUrlString:) object:IMAGE_URL];
// [thread start];/**< 手动开启 */
//三、NSOperation 抽象类 需要用子类初始化,需要加入到线程对垒中进行管理
NSOperationQueue *queue = [[NSOperationQueue alloc]init];//创建多线程队列
//NSInvocationOperation 是NSOperation的子类
NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(loadingImageWithUrlString:) object:IMAGE_URL];
[invocationOperation setCompletionBlock:^{
//更新UI
}];
//加入队列
[queue addOperation:invocationOperation];
//NSBlockOperation
NSBlockOperation *blockOpertion = [NSBlockOperation blockOperationWithBlock:^{
//做线程里面的事,耗时操作
[self loadingImageWithUrlString:IMAGE_URL];
}];
[blockOpertion setCompletionBlock:^{
//更新UI
}];
[queue addOperation:blockOpertion];
//简写 NSBlockOperation
[queue addOperationWithBlock:^{
//做线程里面的事,耗时操作
}];
#pragma mark -- GCD
//四、GCD(中央调度)优势:自动选取CPU内核,线程自己管理
//并发:多个任务同时执行(在异步下才有效果)
//串行:任务一个一个执行
//同步:在当前线程中执行,不具有开辟线程的功能
//异步:开辟一个线程去执行任务,具有开辟线程的能力
//任务(bolck) - 队列(queue)
//dispatch_get_main_queue() 特殊的串行队列,起任务只在主线程中执行
dispatch_async(dispatch_get_main_queue(), ^{
//任务
});
//串行队列
// dispatch_queue_t myQueue = dispatch_queue_create("name",DISPATCH_QUEUE_SERIAL);
//并发队列
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(globalQueue, ^{
//执行任务
//耗时操作
dispatch_async(dispatch_get_main_queue(), ^{
//更新UI
});
});
#pragma mark -- 队列组
//队列组,同时执行多个耗时操作
//创建队列组
dispatch_group_t groupQueue = dispatch_group_create();
dispatch_group_async(groupQueue, globalQueue, ^{
//耗时操作一
});
dispatch_group_async(groupQueue, globalQueue, ^{
//耗时操作二
});
dispatch_group_async(groupQueue, dispatch_get_main_queue(), ^{
//更新UI
});
}
- (void)loadingImageWithUrlString:(NSString *)string{
//从网上获取图片
NSURL *url = [NSURL URLWithString:string];
NSData *data = [NSData dataWithContentsOfURL:url];
//刷新界面 放入主线程中执行
dispatch_async(dispatch_get_main_queue(), ^{
self.contentImageView.image = [UIImage imageWithData:data];
});
self.loadImageView.hidden = YES;
}
#pragma mark -- 线程安全
- (void)openThread{
//创建两个线程同时进行一个操作
NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(countChanged) object:nil];
thread1.name = @"thread1";
[thread1 start];
NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(countChanged) object:nil];
thread2.name = @"thread2";
[thread2 start];
}
- (void)countChanged{
static int count = 20;
// //创建一个死循环
// while (1) {
// //添加线程锁
// [self.lock lock];
//
// NSLog(@"%@ - %d",[NSThread currentThread],count);
// count --;
// if (count < 0) {
// break;
// }
// //解锁
// [self.lock unlock];
// }
@synchronized(self) {
//具有线程安全的
while (1) {
NSLog(@"%@ - %d",[NSThread currentThread],count);
count --;
if (count < 0) {
break;
}
}
}
}