经常使用的GCD
// ViewController.m// 07-GCD的基本使用#import "ViewController.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib.}- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self syncConcurrent];}
这个很重要: 出八阿哥 死循环了?
/** * 同步函数 + 主队列: */ 同步:多个任务一个接着一个的执行,会等待; 异步:多个任务同时都在执行,不会等待;- (void)syncMain{ NSLog(@"syncMain ----- begin"); // 1.获得主队列 dispatch_queue_t queue = dispatch_get_main_queue(); // 2.将任务加入队列 dispatch_sync(queue, ^{ NSLog(@"1-----%@", [NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"2-----%@", [NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"3-----%@", [NSThread currentThread]); }); NSLog(@"syncMain ----- end");}/** * 异步函数 + 主队列:只在主线程中执行任务 */- (void)asyncMain{ // 1.获得主队列 dispatch_queue_t queue = dispatch_get_main_queue(); // 2.将任务加入队列 dispatch_async(queue, ^{ NSLog(@"1-----%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"2-----%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"3-----%@", [NSThread currentThread]); }); }/** * 同步函数 + 串行队列:不会开启新的线程,在当前线程执行任务。任务是串行的,执行完一个任务,再执行下一个任务 */大概就是默认的状态了,在一条道上一个任务接着一个任务的顺序的执行着;- (void)syncSerial{ // 1.创建串行队列 dispatch_queue_t queue = dispatch_queue_create("com.520it.queue", DISPATCH_QUEUE_SERIAL); // 2.将任务加入队列 dispatch_sync(queue, ^{ NSLog(@"1-----%@", [NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"2-----%@", [NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"3-----%@", [NSThread currentThread]); });}/** * 异步函数 + 串行队列:会开启新的线程,但是任务是串行的,执行完一个任务,再执行下一个任务 */在子线程上一个接着一个的执行任务;- (void)asyncSerial{ // 1.创建串行队列 dispatch_queue_t queue = dispatch_queue_create("com.520it.queue", DISPATCH_QUEUE_SERIAL);// dispatch_queue_t queue = dispatch_queue_create("com.520it.queue", NULL); // 2.将任务加入队列 dispatch_async(queue, ^{ NSLog(@"1-----%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"2-----%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"3-----%@", [NSThread currentThread]); });}/** * 同步函数 + 并发队列:不会开启新的线程 */- (void)syncConcurrent{ // 1.获得全局的并发队列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 2.将任务加入队列 dispatch_sync(queue, ^{ NSLog(@"1-----%@", [NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"2-----%@", [NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"3-----%@", [NSThread currentThread]); }); NSLog(@"syncConcurrent--------end");}/** * 异步函数 + 并发队列:可以同时开启多条线程 */- (void)asyncConcurrent{ // 1.创建一个并发队列 // label : 相当于队列的名字 并行的队列 串行的队列// dispatch_queue_t queue = dispatch_queue_create("com.520it.queue", DISPATCH_QUEUE_CONCURRENT); //DISPATCH_QUEUE_SERIAL
//dispatch_queue_create(<#const char * _Nullable label#>, <#dispatch_queue_attr_t _Nullable attr#>)
// 1.获得全局的并发队列:不用自己创建名字都省了 -并发 这个参数是队列的优先级 取值有四种 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 2.将任务加入队列 dispatch_async(queue, ^{ for (NSInteger i = 0; i<10; i++) { NSLog(@"1-----%@", [NSThread currentThread]); } }); dispatch_async(queue, ^{ for (NSInteger i = 0; i<10; i++) { NSLog(@"2-----%@", [NSThread currentThread]); } }); dispatch_async(queue, ^{ for (NSInteger i = 0; i<10; i++) { NSLog(@"3-----%@", [NSThread currentThread]); } }); NSLog(@"asyncConcurrent--------end");// dispatch_release(queue);}@end
08-掌握-GCD-线程间的通信
在子线程中下载图片,下载完成后回到主线程中显示图片;
// ViewController.m// 08-掌握-GCD-线程间的通信#import "ViewController.h"@interface ViewController ()@property (weak, nonatomic) IBOutlet UIImageView *imageView; //来自storyboard拖拽的控件;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib.}- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 首先开启异步;--拿到全局并行队列; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 图片的网络路径 NSURL *url = [NSURL URLWithString:@"http://img.pconline.com.cn/images/photoblog/9/9/8/1/9981681/200910/11/1255259355826.jpg"]; // 加载图片 NSData *data = [NSData dataWithContentsOfURL:url]; // 生成图片 UIImage *image = [UIImage imageWithData:data]; // 回到主线程 dispatch_async(dispatch_get_main_queue(), ^{ self.imageView.image = image; }); });}@end
09-掌握-GCD的其他常用函数 从网路下载两张图片,合并成一张图片并显示; 下载合成的过程放到子线程中;
// ViewController.m// 09-掌握-GCD的其他常用函数#import "ViewController.h"#import "XMGPerson.h"@interface ViewController ()@property (weak, nonatomic) IBOutlet UIImageView *imageView;/** 图片1 */@property (nonatomic, strong) UIImage *image1;/** 图片2 */@property (nonatomic, strong) UIImage *image2;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; XMGPerson *person1 = [[XMGPerson alloc] init]; XMGPerson *person2 = [[XMGPerson alloc] init]; XMGPerson *person3 = [[XMGPerson alloc] init]; XMGPerson *person4 = [[XMGPerson alloc] init]; // XMGPerson *p1 = [[XMGPerson alloc] init];// NSLog(@"%@", p1.books);// // XMGPerson *p2 = [[XMGPerson alloc] init];// NSLog(@"%@", p2.books);}void download(void * data){}- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {// dispatch_async(<#dispatch_queue_t queue#>, <#^(void)block#>);// dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);// dispatch_async_f(queue, NULL, download); //对应的函数 [self group];}- (void)group{ //拿到全局的并行队列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 创建一个队列组 dispatch_group_t group = dispatch_group_create(); // 1.下载图片1 dispatch_group_async(group, queue, ^{ // 图片的网络路径 NSURL *url = [NSURL URLWithString:@"http://img.pconline.com.cn/images/photoblog/9/9/8/1/9981681/200910/11/1255259355826.jpg"]; // 加载图片 NSData *data = [NSData dataWithContentsOfURL:url]; // 生成图片 self.image1 = [UIImage imageWithData:data]; }); // 2.下载图片2 dispatch_group_async(group, queue, ^{ // 图片的网络路径 NSURL *url = [NSURL URLWithString:@"http://pic38.nipic.com/20140228/5571398_215900721128_2.jpg"]; // 加载图片 NSData *data = [NSData dataWithContentsOfURL:url]; // 生成图片 self.image2 = [UIImage imageWithData:data]; }); // 3.将图片1、图片2合成一张新的图片 dispatch_group_notify(group, queue, ^{ // 开启新的图形上下文 UIGraphicsBeginImageContext(CGSizeMake(100, 100)); // 绘制图片 [self.image1 drawInRect:CGRectMake(0, 0, 50, 100)]; [self.image2 drawInRect:CGRectMake(50, 0, 50, 100)]; // 取得上下文中的图片 UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); // 结束上下文 UIGraphicsEndImageContext(); // 回到主线程显示图片 dispatch_async(dispatch_get_main_queue(), ^{ // 4.将新图片显示出来 self.imageView.image = image; }); });}/** * 快速迭代 */- (void)apply{ dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); NSString *from = @"/Users/xiaomage/Desktop/From"; NSString *to = @"/Users/xiaomage/Desktop/To"; NSFileManager *mgr = [NSFileManager defaultManager]; NSArray *subpaths = [mgr subpathsAtPath:from]; dispatch_apply(subpaths.count, queue, ^(size_t index) { NSString *subpath = subpaths[index]; 取出了数组里的文件 NSString *fromFullpath = [from stringByAppendingPathComponent:subpath]; NSString *toFullpath = [to stringByAppendingPathComponent:subpath]; // 剪切 [mgr moveItemAtPath:fromFullpath toPath:toFullpath error:nil]; NSLog(@"%@---%@", [NSThread currentThread], subpath); });}/** * 传统文件剪切 */- (void)moveFile{ NSString *from = @"/Users/xiaomage/Desktop/From"; //旧的文件路径 NSString *to = @"/Users/xiaomage/Desktop/To"; //新的文件路径 NSFileManager *mgr = [NSFileManager defaultManager];//拿到文件管理对象; NSArray *subpaths = [mgr subpathsAtPath:from]; //传一个文件夹路径参数,返回的是这个文件夹下的所有文件包括自文件夹和文件; 返回的是一个文件名(字符串)的数组; for (NSString *subpath in subpaths) { //遍历数组里的文件 for 循环 从from这个路径拼接一个文件名; NSString *fromFullpath = [from stringByAppendingPathComponent:subpath]; // 得到完整的路径; NSString *toFullpath = [to stringByAppendingPathComponent:subpath]; // 得到完整的路径;
异步执行多条线程 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 剪切 [mgr moveItemAtPath:fromFullpath toPath:toFullpath error:nil]; //从一个路径去另个路径; }); }}- (void)once{ 全局性的整个程序运行过程中只运行一次;运行完后这个代码就等于没有了; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSLog(@"------run"); //这里的面的内容是很安全的多个线程不会同时执行; });}/** * 延迟执行 */- (void)delay{ NSLog(@"touchesBegan-----"); // [self performSelector:@selector(run) withObject:nil afterDelay:2.0]; // dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ // NSLog(@"run-----"); // }); [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:NO];}- (void)run{ NSLog(@"run-----");}- (void)barrier{ dispatch_queue_t queue = dispatch_queue_create("12312312", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ NSLog(@"----1-----%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"----2-----%@", [NSThread currentThread]); }); dispatch_barrier_async(queue, ^{ //等前面两个任务执行完了在执行这个任务; NSLog(@"----barrier-----%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"----3-----%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"----4-----%@", [NSThread currentThread]); });}@end
XMGPerson 对象;
//// XMGPerson.h// 09-掌握-GCD的其他常用函数#import@interface XMGPerson : NSObject/** 书本 */@property (nonatomic, strong) NSArray *books;@end
//// XMGPerson.m// 09-掌握-GCD的其他常用函数#import "XMGPerson.h"@implementation XMGPerson- (NSArray *)books{ if (_books == nil) { _books = @[@"1分钟突破iOS开发", @"5分钟突破iOS开发"]; } // static dispatch_once_t onceToken;// dispatch_once(&onceToken, ^{// _books = @[@"1分钟突破iOS开发", @"5分钟突破iOS开发"];// }); return _books;}@end