GCD (Grand Central Dispatch)
GCD: 将应用程序需要执行的工作拆分为可分散在多个线程和多个CPU 上更小的块
demo 效果图:
1—— .h 文件
#import <UIKit/UIKit.h> @interface ViewController : UIViewController - (IBAction)doWork:(id)sender; @property (retain, nonatomic) IBOutlet UIButton *StartBtn; @property (retain, nonatomic) IBOutlet UITextView *resultTextView; @property (retain, nonatomic) IBOutlet UIActivityIndicatorView *spinner; @end
2— .m 文件
#import "ViewController.h" @implementation ViewController @synthesize StartBtn; @synthesize resultTextView; @synthesize spinner; - (NSString *)fetchSomethingFromServer { //将应用程序锁定 1 秒 [NSThread sleepForTimeInterval:1]; return @"hi there"; } - (NSString *)processData:(NSString *)data { [NSThread sleepForTimeInterval:2]; return [data uppercaseString]; } - (NSString *)calculateFirstResult:(NSString *)data { [NSThread sleepForTimeInterval:3]; return [NSString stringWithFormat:@"number of chars :%d",[data length]]; } - (NSString *)calculateSecondResult:(NSString *)data { [NSThread sleepForTimeInterval:4]; return [data stringByReplacingOccurrencesOfString:@"E" withString:@"e"]; } - (IBAction)doWork:(id)sender{ StartBtn.enabled = NO; StartBtn.alpha = 0.5; [spinner startAnimating]; NSDate *startTime = [NSDate date]; // dispatch_get_global_queue(dispatch_queue_priority_t priority, unsigned long flags) // dispatch_get_global_queue() 抓取一个已经存在并且始终可用的全局队列 该函数接收俩个参数: // 1_用于指定优先级(传入0表示使用默认的优先级) ,2_目前未使用并且始终为0() dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSString *fetchedData = [self fetchSomethingFromServer]; NSString *processedData = [self processData:fetchedData]; // NSString *firstResult = [self calculateFirstResult:processedData]; // NSString *secondResult = [self calculateSecondResult:processedData]; //calculateFirstResult && calculateSecondResult 不需要顺序执行 ,并发的执行他们可以更显著的提高速度。 // GCD 提供一种途径来完成此任务,使用所谓的“分派组”,将一个组上 的 上下文中通过 dispatch_group_async() 函数异步分派的所有程序块设置为松散的,以尽可能快的执行,如果可能,将它们分发给多个线程来执行。 // 也可以使用dispathch_group_notify() 指定一个 额外的程序块,该程序块将在组中的所有程序块即将运行完成时执行。 __block NSString *firstResult; __block NSString *secondResult; dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{ firstResult = [[self calculateFirstResult:processedData]retain]; }); dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{ secondResult = [[self calculateSecondResult:processedData]retain]; }); // 使用dispathch_group_notify() 指定一个 额外的程序块,该程序块将在组中的所有程序块即将运行完成时执行。 dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{ NSString *resultsSummary = [NSString stringWithFormat:@"first :[%@] \n second: [%@] \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; [spinner stopAnimating]; resultTextView.text = resultsSummary; }); NSDate *endTime = [NSDate date]; NSLog(@"complete in %f seconds",[endTime timeIntervalSinceDate:startTime]); // 在最后一个程序块中释放 它们, [firstResult release]; [secondResult release]; }); }) ; } #pragma mark - View lifecycle - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } - (void)viewDidUnload { [self setStartBtn:nil]; [self setResultTextView:nil]; [self setSpinner:nil]; [super viewDidUnload]; // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; } - (void)dealloc { [StartBtn release]; [resultTextView release]; [spinner release]; [super dealloc]; } @end
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。