多线程-GCD
多线程-GCD-串行并行
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//GCD -- 基于C语言的一套API/接口 用法非常简单,它是把block作为任务,添加到队列中进行操作
//缺点:不能取消线程
//GCD语法都是C语言函数
//1.创建队列
dispatch_queue_t queue = dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT);
//queue 队列/线程池
//dispatch 调度/执行
//第一个参数:队列的名字 通常写nil
//第二个参数:选择执行方式(串行 并行)
//DISPATCH_QUEUE_SERIAL 串行
//DISPATCH_QUEUE_CONCURRENT 并行
//串行:按照添加到队列里的顺序依次执行线程
//并行:不按照顺序执行线程 同时执行若干个线程
[self createQueue1];
[self createQueue2];
//创建全局队列(并行队列)全局队列放的都是子线程,耗时的操作放到全局队列里
// queue = dispatch_get_global_queue(0, 0);
//第一个参数:通常就写0 第二个参数:选择优先级通常使用默认优先级
/*
#define DISPATCH_QUEUE_PRIORITY_HIGH 2
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
#define DISPATCH_QUEUE_PRIORITY_LOW (-2)
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN
*/
//主队列 相当于拿到主线程
// queue = dispatch_get_main_queue();
//同步执行 使用很少
//下面这种写法会造成线程的相互等待/死循环
// dispatch_sync(dispatch_get_main_queue(), ^{
// NSLog(@"同步执行");
// });
NSLog(@"主线程");
}
- (void)createQueue1{
//创建串行的队列
dispatch_queue_t queue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL);
//将线程放到队列里执行
//async 异步执行 把block作为任务/线程
dispatch_async(queue, ^{
NSLog(@"串行-%@-1",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"串行-%@-2",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"串行-%@-3",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"串行-%@-4",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"串行-%@-5",[NSThread currentThread]);
});
//当前队列里有5个任务 这个5个任务会依次执行
}
- (void)createQueue2{
//创建并行队列
dispatch_queue_t queue = dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"并行-%@-1",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"并行-%@-2",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"并行-%@-3",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"并行-%@-4",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"并行-%@-5",[NSThread currentThread]);
});
//并行 5个线程同时执行
}
@end
多线程-GCD.png
GCD-线程的通讯、延时操作、定时器
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic,strong) UIImageView *imageView;
//使用GCD定时器 需要将它定义成全局变量
@property (nonatomic,strong) dispatch_source_t timer;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.imageView = [[UIImageView alloc]initWithFrame:self.view.bounds];
[self.view addSubview:self.imageView];
[self createQueue1];
// [self createQueue2];
// [self createQueue3];
}
- (void)createQueue1{
//创建全局队列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//异步请求数据
dispatch_async(queue, ^{
//创建子线程的目的:把耗时的操作放到子线程中
//操作 -- 任务 -- 若干行代码(函数 block)
NSURL *url = [NSURL URLWithString:@"http://onepiece.local/SH/1.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
//延时
[NSThread sleepForTimeInterval:2.f];
//让主线程显示数据
//异步执行 让主队列执行
dispatch_async(dispatch_get_main_queue(), ^{
//显示数据
self.imageView.image = image;
});
});
}
- (void)createQueue2{
NSLog(@"将要延时");
//延时几秒操作
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//DISPATCH_TIME_NOW 从现在开始
//NSEC_PER_SEC 秒
//延时几秒之后的操作
NSLog(@"延时执行");
});
//NSObject的延时操作方法
// [self performSelector:@selector(afterRun) withObject:nil afterDelay:2.f];
// //取消延时操作
// [NSObject cancelPreviousPerformRequestsWithTarget:self];
}
- (void)afterRun{
NSLog(@"也是延时操作");
}
- (void)createQueue3{
//GCD定时器
//1.创建定时器
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
//2.设置定时器
dispatch_source_set_timer(self.timer, DISPATCH_TIME_NOW, 2.f * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
//3. 定时器定时的操作
dispatch_source_set_event_handler(self.timer, ^{
//定时器每个几秒钟要做的事情
NSLog(@"GCD定时器");
});
//4.执行定时器
dispatch_resume(self.timer);
//NSTimer定时器 相对于GCD定时器更加精确
// [NSTimer scheduledTimerWithTimeInterval:2.f
// target:self
// selector:@selector(timerRun) userInfo:nil
// repeats:YES];
}
- (void)timerRun{
NSLog(@"NSTimer定时器");
}
@end
GCD-线程组
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self createGroup1];
}
- (void)createGroup1{
//创建线程组
dispatch_group_t group = dispatch_group_create();
//创建全局队列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//异步执行线程组
dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:2.f];
NSLog(@"线程1执行完毕");
});
dispatch_group_async(group, queue, ^{
[NSThread sleepForTimeInterval:4.f];
NSLog(@"线程2执行完毕");
});
// dispatch_group_async(group, queue, ^{
//
// NSLog(@"线程3执行完毕");
// });
//前两个线程结束后会通知这个线程 接到通知后在运行当前线程
// dispatch_group_notify(group, queue, ^{
//
// NSLog(@"线程3执行完毕");
// });
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"主线程执行");
});
}
GCD-线程组1.png
GCD-信号量、栏栅、重复
- (void)crerateGroup2{
dispatch_group_t group = dispatch_group_create();
//异步操作
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
for (int i = 0; i < 5; i++) {
//进入线程组
// dispatch_group_enter(group);
[NSThread sleepForTimeInterval:1.f];
NSLog(@"线程---%d",i);
//离开线程组
// dispatch_group_leave(group);
}
});
//目的:先执行完前面的线程 在执行后面的线程
//阻塞线程
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
//DISPATCH_TIME_FOREVER 直到永远
//异步操作
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"另一个线程执行了");
});
}
GCD-线程组2.png
#import "ViewController.h"
@interface ViewController ()
@property (strong, nonatomic) UIImageView *imageView1;
@property (strong, nonatomic) UIImageView *imageView2;
@property (strong, nonatomic) UIImageView *imageView3;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// [self createQueue1];
// [self createQueue2];
// [self createQueue3];
[self createQueue4];
}
- (void)createQueue1{
//重复执行某个线程
//第一个参数:要重复执行几次
dispatch_apply(50, dispatch_get_global_queue(0, 0), ^(size_t num) {
NSLog(@"线程执行了...");
});
}
- (void)createQueue2{
dispatch_queue_t queue = dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
sleep(1);
NSLog(@"线程1...");
});
dispatch_async(queue, ^{
sleep(1);
NSLog(@"线程2...");
});
//barrier 屏障 前面的线程完之后 在执行当前线程和后面的线程
dispatch_barrier_async(queue, ^{
NSLog(@"线程3...");
});
dispatch_async(queue, ^{
// sleep(1);
NSLog(@"线程4...");
});
}
- (void)createQueue3{
//信号量
//创建信号量
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//等待接收信号 接收信号要写在当前线程所有操作之前
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"线程1执行了...");
});
dispatch_async(dispatch_get_global_queue(0, 0), ^{
sleep(1);
NSLog(@"线程2执行了...");
//发送信号 在当前线程操作执行完毕之后 在发送信号
dispatch_semaphore_signal(semaphore);
});
}
- (void)createQueue4{
self.imageView1 = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 300, 100)];
self.imageView2 = [[UIImageView alloc]initWithFrame:CGRectMake(0, 100, 300, 100)];
self.imageView3 = [[UIImageView alloc]initWithFrame:CGRectMake(0, 200, 300, 100)];
self.imageView1.alpha = 0;
self.imageView2.alpha = 0;
self.imageView3.alpha = 0;
[self.view addSubview:self.imageView1];
[self.view addSubview:self.imageView2];
[self.view addSubview:self.imageView3];
//创建信号量
dispatch_semaphore_t sem = dispatch_semaphore_create(0);
dispatch_semaphore_t sem2 = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//子线程 下载数据
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://onepiece.local/SH/1.jpg"]];
dispatch_async(dispatch_get_main_queue(), ^{
//主线程 显示数据
[UIView animateWithDuration:2.f animations:^{
self.imageView1.image = [UIImage imageWithData:data];
self.imageView1.alpha = 1.0;
} completion:^(BOOL finished) {
//显示完成后 发送信号
dispatch_semaphore_signal(sem);
}];
});
});
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//子线程 下载数据
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://onepiece.local/SH/2.jpg"]];
dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
dispatch_async(dispatch_get_main_queue(), ^{
//主线程 显示数据
[UIView animateWithDuration:2.f animations:^{
self.imageView2.image = [UIImage imageWithData:data];
self.imageView2.alpha = 1.0;
} completion:^(BOOL finished) {
dispatch_semaphore_signal(sem2);
}];
});
});
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//子线程 下载数据
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://onepiece.local/SH/3.jpg"]];
dispatch_semaphore_wait(sem2, DISPATCH_TIME_FOREVER);
dispatch_async(dispatch_get_main_queue(), ^{
//主线程 显示数据
[UIView animateWithDuration:2.f animations:^{
self.imageView3.image = [UIImage imageWithData:data];
self.imageView3.alpha = 1.0;
} completion:^(BOOL finished) {
}];
});
});
}
@end
GCD-信号量实例
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic,strong) UIImageView *imageView1;
@property (nonatomic,strong) UIImageView *imageView2;
@property (nonatomic,strong) UIImageView *imageView3;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.imageView1 = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height/3)];
self.imageView1.alpha = 0;
[self.view addSubview:self.imageView1];
self.imageView2 = [[UIImageView alloc]initWithFrame:CGRectMake(0, self.view.bounds.size.height/3, self.view.bounds.size.width, self.view.bounds.size.height/3)];
self.imageView2.alpha = 0;
[self.view addSubview:self.imageView2];
self.imageView3 = [[UIImageView alloc]initWithFrame:CGRectMake(0, 2*self.view.bounds.size.height/3, self.view.bounds.size.width, self.view.bounds.size.height/3)];
self.imageView3.alpha = 0;
[self.view addSubview:self.imageView3];
//http://onepiece.local/SH/1.jpg
//http://onepiece.local/SH/2.jpg
//http://onepiece.local/SH/3.jpg
//创建信号量
dispatch_semaphore_t sem1 = dispatch_semaphore_create(0);
dispatch_semaphore_t sem2 = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//子线程 下载数据
NSURL *url = [NSURL URLWithString:@"http://onepiece.local/SH/1.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
//主线程显示数据/刷新UI
dispatch_async(dispatch_get_main_queue(), ^{
[UIView animateWithDuration:2.f animations:^{
self.imageView1.image = [UIImage imageWithData:data];
self.imageView1.alpha = 1.f;
} completion:^(BOOL finished) {
//第一张图片显示完之后 给第个线程发送信号 让第二张图片显示
dispatch_semaphore_signal(sem1);
}];
});
});
//第二个线程
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//子线程 下载数据
NSURL *url = [NSURL URLWithString:@"http://onepiece.local/SH/2.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
//等待信号量sem1 直到接收到sem1这个信号量 再继续向下执行
dispatch_semaphore_wait(sem1, DISPATCH_TIME_FOREVER);
//主线程显示数据/刷新UI
dispatch_async(dispatch_get_main_queue(), ^{
[UIView animateWithDuration:2.f animations:^{
self.imageView2.image = [UIImage imageWithData:data];
self.imageView2.alpha = 1.f;
} completion:^(BOOL finished) {
//第二张图片显示完成 给线程3发送信号 让第三张图片显示
dispatch_semaphore_signal(sem2);
}];
});
});
//第三个线程
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//子线程 下载数据
NSURL *url = [NSURL URLWithString:@"http://onepiece.local/SH/3.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
//等待信号量sem2 然后再继续向下执行
dispatch_semaphore_wait(sem2, DISPATCH_TIME_FOREVER);
//主线程显示数据/刷新UI
dispatch_async(dispatch_get_main_queue(), ^{
[UIView animateWithDuration:2.f animations:^{
self.imageView3.image = [UIImage imageWithData:data];
self.imageView3.alpha = 1.f;
} completion:^(BOOL finished) {
}];
});
});
}
@end
网友评论