小编在前一篇中介绍了多线程实现的五种经常使用方法。在接下来所介绍的这种方法是最具备魅力的,最具备诱惑的实现多线程的方案---GCDweb
1、什么是GCD缓存
GCD是Grand Central Dispatch的简称,是基于C语言的。若是使用GCD,彻底由系统管理线程,咱们不须要编写线程代码。只需定义想要执行的任务,而后添加到适当的调度队列(dispatch queue)。GCD会负责建立线程和调度你的任务,系统直接提供线程管理,大大的提升代码的执行效率与多核的利用率。
1.GCD的一个重要概念是队列,它的核心理念:将长期运行的任务拆分红多个工做单元,并将这些单元添加到dispath queue中,系统会为咱们管理这些dispath queue,为咱们在多个线程上执行工做单元,咱们不须要直接启动和管理后台线程。多线程
2.系统提供了许多预约义的dispath queue,包括能够保证始终在主线程上执行工做的dispath queue。也能够建立本身的dispath queue,并且能够建立任意多个。GCD的dispath queue严格遵循FIFO(先进先出)原则,添加到dispath queue的工做单元将始终按照加入dispath queue的顺序启动。并发
3.dispatch queue按先进先出的顺序,串行或并发地执行任务异步
2、建立和管理GCDasync
并发dispatch queue能够同时并行地执行多个任务,不过并发queue仍然按先进先出的顺序来启动任务。并发queue会在以前的任务完成以前就出列下一个任务并开始执行。并发queue同时执行的任务数量会根据应用和系统动态变化,各类因素包括:可用核数量、其它进程正在执行的工做数量、其它串行dispatch queue中优先任务的数量等.函数
1 //建立一个队列 2 dispatch_queue_attr_t queue = dispatch_queue_create("test", NULL); 3 /********此种方式是异步多线程的运行*********/ 4 dispatch_async(queue, ^{ 5 for (int i = 0; i < 100; i++) { 6 NSLog(@"---这是多线程---%d",i); 7 } 8 9 //回到主线程 10 dispatch_sync(dispatch_get_main_queue(), ^{ 11 BOOL isMain = [NSThread isMainThread]; 12 if (isMain) { 13 NSLog(@"isMain"); 14 } 15 }); 16 }); 17 18 /********此种方式是同步多线程的运行*********/ 19 dispatch_sync(queue, ^{ 20 //demo 21 });
GCD提供了函数让应用访问几个公共dispatch queue:测试
1> 使用dispatch_get_current_queue函数做为调试用途,或者测试当前queue的标识。在block对象中调用这个函数会返回 block提交到的queue(这个时候queue应该正在执行中)。在block对象以外调用这个函数会返回应用的默认并发queue。
2> 使用dispatch_get_main_queue函数得到应用主线程关联的串行dispatch queue
备注:在新建立的子线程中,须要添加自动释放池来管理内存。
GCD支持Cocoa内存管理机制,所以能够在提交到queue的 block中自由地使用Objective-C对象。每一个dispatch queue维护本身的autorelease pool确保释放autorelease对象,可是queue不保证这些对象实际释放的时间。若是应用消耗大量内存,而且建立大量autorelease 对象,你须要建立本身的autorelease pool,用来及时地释放再也不使用的对象。url
3、暂停和继续queuespa
咱们能够使用dispatch_suspend函数暂 停一个queue以阻止它执行block对象;使用dispatch_resume函数继续dispatch queue。调用dispatch_suspend会增长queue的引用计数,调用dispatch_resume则减小queue的引用计数。当引用 计数大于0时,queue就保持挂起状态。所以你必须对应地调用suspend和resume函数。挂起和继续是异步的,并且只在执行block之间(比 如在执行一个新的block以前或以后)生效。挂起一个queue不会致使正在执行的block中止。
4、案例
小编经过使用GCD的实现方法,经过URL来异步存储图片。
1 @implementation UIImageView (webCach) 2 - (void)setUIImageWithUrl:(NSURL*)url 3 { 4 //使用异步线程来下载 5 dispatch_queue_t queue = dispatch_queue_create("imageLoad", NULL); 6 dispatch_async(queue, ^{ 7 NSData *data = [NSData dataWithContentsOfURL:url]; 8 UIImage *image = [UIImage imageWithData:data]; 9 //主线程 10 dispatch_sync(dispatch_get_main_queue(), ^{ 11 self.image = image; 12 }); 13 }); 14 15 } 16 @end
1 - (void)viewDidLoad { 2 3 [super viewDidLoad]; 4 5 UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 320, 500)]; 6 [imageView setUIImageWithUrl:[NSURL URLWithString:@"http://s1.dwstatic.com/group1/M00/F5/00/f251b9aca3b84a55449f1083e9fe8cda.jpg"]]; 7 [self.view addSubview:imageView]; 8 9 }
当图片异步加载完成后,就会展示出来。可是,第二次进入该界面,仍是要从新下载图片,用户体验很差,且浪费资源(好比耗电)。
因而,考虑缓存已经下载的图片。
小便的能力有限,欢迎大牛指正!!!