iOS:多线程技术GCD的使用
GCD的使用: 1.队列的类型 1.1 主队列:mian queue,主线程队列,负责更行UI的操作。是一个串行的队列。 1.2 系统默认的并行队列:global queue,按优先级分类。 1.3 自定义的队列:可以创建串行队列或者是并行的队列 2.任务 2.1 封装的形式:block方法或C语言的函数 2.2 添加到队列的方式:同步或异步(只对并行队列有区别) 例如服务器请求: 同步:提交请求->等待服务器处理(这个期间客户端浏览器不能干任何事)->处理完毕返回 异步:请求通过事件触发->服务器处理(这个期间客户端浏览器仍可以干其他的事)->处理完毕返回 3.特殊使用 3.1 只执行一次 dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);(多用于单例模式) 3.2 延时执行 dispatch_after(dispatch_time_twhen,dispatch_queue_tqueue,dispatch_block_t block); 3.3 成组的执行任务 dispatch_group_create(void); 3.4 创建自定义的队列 dispatch_queue_create(constchar*label,dispatch_queue_attr_tattr); 3.5 创建默认的全局队列dispatch_get_global_queue(longidentifier,unsignedlongflags) 3.6 获取主队列 dispatch_get_main_queue(void) 3.7 异步执行 dispatch_async(dispatch_queue_tqueue,dispatch_block_tblock); 3.8 同步执行 dispatch_sync(dispatch_queue_tqueue,dispatch_block_tblock); 3.9 多次执行 dispatch_apply(size_titerations,dispatch_queue_tqueue,void (^block)(size_t)); …………………等等………………… 4.几个方法参数解释: <1>创建自定义的队列 dispatch_queue_create(constchar*label,dispatch_queue_attr_tattr); constchar*label:队列名字 dispatch_queue_attr_tattr:队列执行方式(串行、并行) <2>创建默认的全局队列dispatch_get_global_queue(longidentifier,unsignedlongflags) longidentifier:队列执行的优先级 unsignedlongflags:默认为0即可 <3>多次执行 dispatch_apply(size_titerations,dispatch_queue_tqueue,void(^block)(size_t)); size_titerations:执行次数 dispatch_queue_tqueue:队列 void(^block)(size_t):block函数块 5.队列方式宏定义(用于创建自定义队列时的参数) #define DISPATCH_QUEUE_SERIAL NULL //串行 #define DISPATCH_QUEUE_CONCURRENT //并行 6.队列优先级宏定义(创建全局队列时的参数) #define DISPATCH_QUEUE_PRIORITY_HIGH2 #define DISPATCH_QUEUE_PRIORITY_DEFAULT0 #define DISPATCH_QUEUE_PRIORITY_LOW (-2) #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN 7.更能区分 主队列:专门用来执行主线程的,进行UI的更新操作 全局队列或自定义队列:用来添加并执行其他的线程,进行数据的操作 具体举例如下: 例子1:采用不分组的方式,将多线程添加到队列中,然后进行多线程的操作。 1.准备UI界面布局:拖入一个文本视图控件,并关联相关的类中,同时在类中声明一个票数变量 @interface ViewController () { NSInteger _tickets; } @property (weak, nonatomic) IBOutlet UITextView *textView; @end 2.设置票数,同时将原来文本视图中默认的数据清空,取消自动布局便于后面添加数据时自动滚动文本视图 //设置数据和文本视图 _tickets = 20; [self.textView setText:@""]; self.textView.layoutManager.allowsNonContiguousLayout = NO; 3.创建全局队列,并设置优先级,设置并行方式 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 4.用GCD创建任务线程,并将线程添加到队列中,采用异步执行方式 dispatch_async(queue, ^{ [self GCDSellTicketMethod:@"GCD售票线程-1"]; }); dispatch_async(queue, ^{ [self GCDSellTicketMethod:@"GCD售票线程-2"]; }); 5.定义更新UI的方法 #pragma mark -更新UI的操作 -(void)appendTextView:(NSString *)text { //1.获取原来的数据 NSMutableString *content = [NSMutableString stringWithString:self.textView.text]; NSRange range = NSMakeRange(content.length, 2); //2.追加新的内容 [content appendString:[NSString stringWithFormat:@"\n%@",text]]; [self.textView setText:content]; //3.滚动视图 [self.textView scrollRangeToVisible:range]; } 6.定义任务线程的执行方法 #pragma mark -执行线程的操作 -(void)GCDSellTicketMethod:(NSString *)name { while (YES) { if(_tickets > 0) { //使用GCD dispatch_async(dispatch_get_main_queue(), ^{ //更新UI NSString *info = [NSString stringWithFormat:@"总票数:%ld,当前的线程:%@",_tickets,name]; [self appendTextView:info]; //卖票 _tickets--; }); //线程休眠 if([name isEqualToString:@"GCD售票线程-1"]) { [NSThread sleepForTimeInterval:0.3f]; } else { [NSThread sleepForTimeInterval:0.2f]; } } else { //使用GCD更新UI dispatch_async(dispatch_get_main_queue(), ^{ NSString *info = [NSString stringWithFormat:@"票已经卖完,当前线程:%@",name]; [self appendTextView:info]; }); //退出线程 break; } } } 例子2:采用分组的方式,将线程组添加到队列中,然后进行多线程的操作。 1.准备UI界面布局:拖入一个文本视图控件,并关联相关的类中,同时在类中声明一个票数变量 @interface ViewController () { NSInteger _tickets; } @property (weak, nonatomic) IBOutlet UITextView *textView; @end 2.设置票数,同时将原来文本视图中默认的数据清空,取消自动布局便于后面添加数据时自动滚动文本视图 //设置数据和文本视图 _tickets = 20; [self.textView setText:@""]; self.textView.layoutManager.allowsNonContiguousLayout = NO; 3.创建一个线程分组 dispatch_group_t group = dispatch_group_create(); 4.创建自定义的队列,并设置队列执行方式为并行方式 dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT); 5.用GCD创建任务线程组,并将线程组添加到队列中,采用分组异步执行方式 dispatch_group_async(group,queue, ^{ [self GCDSellTicketMethod:@"GCD售票线程-1"]; }); dispatch_group_async(group,queue, ^{ [self GCDSellTicketMethod:@"GCD售票线程-2"]; }); 6.等线程组中的所有任务完成后,会接收到通知,更新UI dispatch_group_notify(group, queue, ^{ dispatch_async(dispatch_get_main_queue(), ^{ NSString *info = [NSString stringWithFormat:@"票已经卖完"]; [self appendTextView:info]; }); }); 7.定义更新UI的方法 #pragma mark -更新UI的操作 -(void)appendTextView:(NSString *)text { //1.获取原来的数据 NSMutableString *content = [NSMutableString stringWithString:self.textView.text]; NSRange range = NSMakeRange(content.length, 2); //2.追加新的内容 [content appendString:[NSString stringWithFormat:@"\n%@",text]]; [self.textView setText:content]; //3.滚动视图 [self.textView scrollRangeToVisible:range]; } 8.定义任务线程的执行方法 #pragma mark -执行线程的操作 -(void)GCDSellTicketMethod:(NSString *)name { while (YES) { if(_tickets > 0) { //使用GCD dispatch_async(dispatch_get_main_queue(), ^{ //更新UI NSString *info = [NSString stringWithFormat:@"总票数:%ld,当前的线程:%@",_tickets,name]; [self appendTextView:info]; //卖票 _tickets--; }); //线程休眠 if([name isEqualToString:@"GCD售票线程-1"]) { [NSThread sleepForTimeInterval:0.3f]; } else { [NSThread sleepForTimeInterval:0.2f]; } } else { //退出线程 break; } } } 两种情况的演示结果如下: 程序猿神奇的手,每时每刻,这双手都在改变着世界的交互方式! 分类: iOS高级 本文转自当天真遇到现实博客园博客,原文链接:http://www.cnblogs.com/XYQ-208910/p/4859089.html,如需转载请自行联系原作者