程序员人生 网站导航

iOS中 GCD-Grand Central Dispath 多线程 UI_21

栏目:综合技术时间:2016-04-25 13:26:57

 GCD:Grand Central Dispath "牛逼的中枢调度器";是纯C语言编写的,提供了很多比较强大的函数

 GCD:优势

 1.目前是苹果主推的线程管理方式

 2.它会自动的利用更多的CPU资源(双核,4核)

 3.它会自动的管理线程的生命周期(线程的创建/调度/烧毁);

 4.程序员只需要告知GCD自己想要履行的哪些任务,不需要写1行线程管理的代码


#import "ViewController.h" #define kURLString1 @"http://www.nbsheji.cn/uploadfiles/2010113143922418.jpg" #define kURLString2 @"http://amuse.nen.com.cn/imagelist/11/21/9as70n3ir61b.jpg" @interface ViewController () @property (retain, nonatomic) IBOutlet UIImageView *FirstView;//第1个图片 @property (retain, nonatomic) IBOutlet UIImageView *secondView;//第2个图片 @property(nonatomic,retain)NSMutableArray *dataSource;//存储要求下来的数据 @end @implementation ViewController //懒加载 - (NSMutableArray *)dataSource{ if (_dataSource == nil) { self.dataSource = [NSMutableArray arrayWithCapacity:0]; } return [[_dataSource retain]autorelease]; }

串行队列:(线程同步)添加到这个队列的任务1个接1个的履行(1个任务完成,才再去完成另外一个任务)


- (IBAction)handleSerialQueue:(UIButton *)sender { //获得系统串行队列 // (1)向系统的创建的串行队列中添加异步任务,还是在主线程中完成; // (2)向系统创建的串行队列中添加同步任务,会造成线程死锁,致使其他人没法履行; dispatch_queue_t queue1 = dispatch_get_main_queue(); //01:队列的唯1标识,采取反域名情势 //02:队列的属性类型,也就是标识这个队列是串行队列还是并行队列 // (1)自己创建的串行队列中添加异步任务是在子线程中完成任务; // (2)自己创建的串行队列中添加同步任务是在主线程中完成任务; dispatch_queue_t queue2 = dispatch_queue_create("com.xcqnzf.xuchang", DISPATCH_QUEUE_SERIAL); /* //异步任务 //第1个参数:任务添加到队列名称 //第2个参数:block履行任务内容 dispatch_async(queue2, ^{ NSLog(@"任务1 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread); }); dispatch_async(queue2, ^{ NSLog(@"任务2 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread); }); dispatch_async(queue2, ^{ NSLog(@"任务3 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread); }); //释放掉自己的创建的队列,出现create就要释放 dispatch_release(queue2); */ //同步任务 dispatch_sync(queue2, ^{ NSLog(@"任务1 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread); }); dispatch_sync(queue2, ^{ NSLog(@"任务2 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread); }); dispatch_sync(queue2, ^{ NSLog(@"任务3 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread); }); // 总结:同步任务:不管在哪个队列中都是主线程中履行,但是不能将其添加到系统自带的串行队列中; // 异步任务:在自己创建的串行队列中,在子线程中履行,如果是系统创建的队列在主线程中履行; }

2.并行队列 (线程并发) 添加到此队列的任务同时履行  假象

- (IBAction)handleConcurrentQueue:(UIButton *)sender { //1.获得系统自带的并行队列 //01.队列的优先级 //02.预留参数 给0 dispatch_queue_t queue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //2.自己创建并行队列 (1般不自己创建并行队列,系统的并行队列已够用了) dispatch_queue_t queue2 = dispatch_queue_create("com.xcqnzf.xuchang", DISPATCH_QUEUE_CONCURRENT); //同步任务 dispatch_sync(queue1, ^{ NSLog(@"同步任务%@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread); }); //异步任务 dispatch_async(queue2, ^{ NSLog(@"任务1%@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread); }); dispatch_async(queue2, ^{ NSLog(@"任务2%@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread); }); dispatch_async(queue2, ^{ NSLog(@"任务3%@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread); //线程间的通讯 //由子线程回到主线程 //获得系统的串行队列 dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"我回到主线程了"); }); }); //释放出现create就要释放 dispatch_release(queue2); }

3.分组队列:把多个任务添加到1个分组中履行,此时会在所有的任务完成后会自动发1个通

知,dispatch_group_notifity接收这个消息,然后在所有任务完成以后处理


- (IBAction)handleGroupQueue:(UIButton *)sender { //1.创建并行队列,并履行任务 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); __block typeof(self)weakSelf = self; //创建分组异步同步任务 dispatch_group_t group = dispatch_group_create(); //01.分组名 //02.要添加的队列名 //03.要履行的任务 dispatch_group_async(group, queue, ^{ NSURL *urlString = [NSURL URLWithString:kURLString1]; NSData *data1 = [NSData dataWithContentsOfURL:urlString]; //使用数组寄存要求下来的数据 [weakSelf.dataSource addObject:data1]; }); dispatch_group_async(group, queue, ^{ NSURL *url = [NSURL URLWithString:kURLString2]; NSData *data2 = [NSData dataWithContentsOfURL:url]; [weakSelf.dataSource addObject:data2]; }); //分组中的任务都完成后会自动触发下面的方法 dispatch_group_notify(group, queue, ^{ weakSelf.FirstView.image = [UIImage imageWithData:weakSelf.dataSource[0]]; weakSelf.secondView.image = [UIImage imageWithData:weakSelf.dataSource[1]]; }); //释放分组 dispatch_release(group); }


4.障碍队列

- (IBAction)handleBarrierQueue:(UIButton *)sender { //1.使用障碍队列只能使用自己创建的并列队列,不能使用系统的并行队列 dispatch_queue_t queue = dispatch_queue_create("com.xcqnzf.xuchang", DISPATCH_QUEUE_CONCURRENT); //2.往并行队列中添加任务 dispatch_async(queue, ^{ NSLog(@"A写入文件"); }); dispatch_async(queue, ^{ NSLog(@"B写入文件"); }); dispatch_async(queue, ^{ NSLog(@"C写入文件"); }); //添加障碍,间隔写入和读取的任务,障碍任务之前的任务都完成了才能继续完成障碍任务后面的任务 dispatch_barrier_async(queue, ^{ NSLog(@"我是障碍任务,读取的任务先等会"); }); dispatch_async(queue, ^{ NSLog(@"D读取文件"); }); dispatch_async(queue, ^{ NSLog(@"D读取文件"); }); dispatch_async(queue, ^{ NSLog(@"E读取文件"); }); //3.释放 dispatch_release(queue); }


只履行1次

- (IBAction)handleOnce:(UIButton *)sender { static dispatch_once_t oneToken ; // dispatch_once(&oneToken, ^{ NSLog(@"有本事让我走两次"); }); }

这里需要写1个单例

Helper.h @interface Helper : NSObject + (Helper *)shareHelper; @end Helper.h @implementation Helper static Helper *helper = nil; + (Helper *)shareHelper{ //VIP static dispatch_once_t oneToken; dispatch_once(&oneToken, ^{ helper = [[Helper alloc]init]; }); return helper; } @end


重复任务

- (IBAction)handleRepeat:(UIButton *)sender { //1.获得系统的并行队列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //2.向队列中添加重复任务 //01.任务重复的次数 //02.任务添加到的队列名称 //03.当前是第几次重复这个任务 dispatch_apply(10, queue, ^(size_t times) { NSLog(@"我要吃爆米花,这是我第%ld吃",times); }); }

延迟任务 1个任务要履行的时候先等上1段时间再做


- (IBAction)handlePing:(UIButton *)sender { //创建1个延迟任务 //01. DISPATCH_TIME_NOW 表示从当前时间开始 //02. 表示过量少秒才去履行任务 //03. 串行的主队列 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSLog(@"延迟任务在主线程中履行"); }); }
//释放
- (void)dealloc {
    [_FirstView release];
    [_secondView release];
    self.dataSource = nil;
    [super dealloc];
}



分组队列效果:

------分隔线----------------------------
------分隔线----------------------------

最新技术推荐