GCD (Grand Central Dispatch)

GCD:将应用程序需要执行的工作拆分为可分散在多个线程和多个CPU 上更小的块

demo 效果图:

1—— .h 文件

#import<UIKit/UIKit.h>@interfaceViewController:UIViewController-(IBAction)doWork:(id)sender;@property(retain,nonatomic)IBOutletUIButton*StartBtn;@property(retain,nonatomic)IBOutletUITextView*resultTextView;@property(retain,nonatomic)IBOutletUIActivityIndicatorView*spinner;@end

2— .m 文件

#import"ViewController.h"@implementationViewController@synthesizeStartBtn;@synthesizeresultTextView;@synthesizespinner;-(NSString*)fetchSomethingFromServer{//将应用程序锁定1秒[NSThreadsleepForTimeInterval:1];return@"hithere";}-(NSString*)processData:(NSString*)data{[NSThreadsleepForTimeInterval:2];return[datauppercaseString];}-(NSString*)calculateFirstResult:(NSString*)data{[NSThreadsleepForTimeInterval:3];return[NSStringstringWithFormat:@"numberofchars:%d",[datalength]];}-(NSString*)calculateSecondResult:(NSString*)data{[NSThreadsleepForTimeInterval:4];return[datastringByReplacingOccurrencesOfString:@"E"withString:@"e"];}-(IBAction)doWork:(id)sender{StartBtn.enabled=NO;StartBtn.alpha=0.5;[spinnerstartAnimating];NSDate*startTime=[NSDatedate];//dispatch_get_global_queue(dispatch_queue_priority_tpriority,unsignedlongflags)//dispatch_get_global_queue()抓取一个已经存在并且始终可用的全局队列该函数接收俩个参数: // 1_用于指定优先级(传入0表示使用默认的优先级),2_目前未使用并且始终为0()dispatch_async(dispatch_get_global_queue(0,0),^{NSString*fetchedData=[selffetchSomethingFromServer];NSString*processedData=[selfprocessData:fetchedData];//NSString*firstResult=[selfcalculateFirstResult:processedData];//NSString*secondResult=[selfcalculateSecondResult:processedData];//calculateFirstResult&&calculateSecondResult不需要顺序执行,并发的执行他们可以更显著的提高速度。//GCD提供一种途径来完成此任务,使用所谓的“分派组”,将一个组上的上下文中通过dispatch_group_async()函数异步分派的所有程序块设置为松散的,以尽可能快的执行,如果可能,将它们分发给多个线程来执行。//也可以使用dispathch_group_notify()指定一个额外的程序块,该程序块将在组中的所有程序块即将运行完成时执行。__blockNSString*firstResult;__blockNSString*secondResult;dispatch_group_tgroup=dispatch_group_create();dispatch_group_async(group,dispatch_get_global_queue(0,0),^{firstResult=[[selfcalculateFirstResult:processedData]retain];});dispatch_group_async(group,dispatch_get_global_queue(0,0),^{secondResult=[[selfcalculateSecondResult:processedData]retain];});//使用dispathch_group_notify()指定一个额外的程序块,该程序块将在组中的所有程序块即将运行完成时执行。dispatch_group_notify(group,dispatch_get_global_queue(0,0),^{NSString*resultsSummary=[NSStringstringWithFormat:@"first:[%@]\nsecond:[%@]\n",firstResult,secondResult];//resultTextView.text=resultsSummary;//在后台线程联系任何GUI对象是不可能的,必须将工作传回到主线程!可再次调用dispatch_async这次传入dispatch_get_main_queue()函数返回的队列,该函数总是提供存在于主线程上的特殊队列,并准备执行需要使用主线程的程序块dispatch_async(dispatch_get_main_queue(),^{//回到主线程才可以出发按钮事件StartBtn.enabled=YES;StartBtn.alpha=1.0;[spinnerstopAnimating];resultTextView.text=resultsSummary;});NSDate*endTime=[NSDatedate];NSLog(@"completein%fseconds",[endTimetimeIntervalSinceDate:startTime]);//在最后一个程序块中释放它们,[firstResultrelease];[secondResultrelease];});});}#pragmamark-Viewlifecycle-(void)viewDidLoad{[superviewDidLoad];//Doanyadditionalsetupafterloadingtheview,typicallyfromanib.}-(void)viewDidUnload{[selfsetStartBtn:nil];[selfsetResultTextView:nil];[selfsetSpinner:nil];[superviewDidUnload];//Releaseanyretainedsubviewsofthemainview.//e.g.self.myOutlet=nil;}-(void)dealloc{[StartBtnrelease];[resultTextViewrelease];[spinnerrelease];[superdealloc];}@end