GCD的使用:
4.幾個方法參數解釋:
<1>創建自定義的隊列? ??dispatch_queue_create(const?char?*label,?dispatch_queue_attr_t?attr);
const?char?*label:隊列名字 ?? ? ? ? ? ? ? ? ?dispatch_queue_attr_t?attr:隊列執行方式(串行、并行)
<2>創建默認的全局隊列?dispatch_get_global_queue(long?identifier,?unsigned?long?flags)
long?identifier:隊列執行的優先級 ? ? ? ? ??unsigned?long?flags:默認為0即可
<3>多次執行 ? ? ? ??dispatch_apply(size_t?iterations,?dispatch_queue_t?queue,void?(^block)(size_t));
size_t?iterations:執行次數 ? ? ?dispatch_queue_t?queue:隊列 ? ? ?void?(^block)(size_t):block函數塊
#define DISPATCH_QUEUE_SERIAL NULL ? ? ? ? //串行
#define DISPATCH_QUEUE_CONCURRENT ? ? ? ?//并行
?
6.隊列優先級宏定義(創建全局隊列時的參數)
#define DISPATCH_QUEUE_PRIORITY_HIGH?2
#define DISPATCH_QUEUE_PRIORITY_DEFAULT?0
#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){//使用GCDdispatch_async(dispatch_get_main_queue(), ^{//更新UINSString *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更新UIdispatch_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){//使用GCDdispatch_async(dispatch_get_main_queue(), ^{//更新UINSString *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;}}
}
?
兩種情況的演示結果如下:
?
?
?
?
?
?
?