iOS:多线程技术GCD的使用
GCD的使用:
1.隊(duì)列的類型 ? ? ?1.1 主隊(duì)列:mian queue,主線程隊(duì)列,負(fù)責(zé)更行UI的操作。是一個(gè)串行的隊(duì)列。 ? ? ?1.2 系統(tǒng)默認(rèn)的并行隊(duì)列:global queue,按優(yōu)先級(jí)分類。 ? ? ?1.3 自定義的隊(duì)列:可以創(chuàng)建串行隊(duì)列或者是并行的隊(duì)列 ? 2.任務(wù) ? ? ?2.1 封裝的形式:block方法或C語言的函數(shù) ? ? ?2.2 添加到隊(duì)列的方式:同步或異步(只對(duì)并行隊(duì)列有區(qū)別) ? ? ? ? ?例如服務(wù)器請(qǐng)求: ? ? ? ? ?同步:提交請(qǐng)求->等待服務(wù)器處理(這個(gè)期間客戶端瀏覽器不能干任何事)->處理完畢返回 ?? ? ? ? ? ?異步:請(qǐng)求通過事件觸發(fā)->服務(wù)器處理(這個(gè)期間客戶端瀏覽器仍可以干其他的事)->處理完畢返回 ? 3.特殊使用 ? ? ?3.1 只執(zhí)行一次 dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);(多用于單例模式) ? ? ?3.2 延時(shí)執(zhí)行 ? ?dispatch_after(dispatch_time_t?when,dispatch_queue_t??queue,dispatch_block_t block); ? ? ?3.3 成組的執(zhí)行任務(wù) ? ? ??dispatch_group_create(void); ? ? ?3.4 創(chuàng)建自定義的隊(duì)列? ??dispatch_queue_create(const?char?*label,?dispatch_queue_attr_t?attr); ? ? ?3.5 創(chuàng)建默認(rèn)的全局隊(duì)列?dispatch_get_global_queue(long?identifier,?unsigned?long?flags) ? ? ?3.6 獲取主隊(duì)列 ? ? ? ? ? ??dispatch_get_main_queue(void) ? ? ?3.7 異步執(zhí)行 ? ? ? ? ? ? ? ?dispatch_async(dispatch_queue_t?queue,?dispatch_block_t?block); ? ? ?3.8 同步執(zhí)行 ? ? ? ? ? ? ?dispatch_sync(dispatch_queue_t?queue,?dispatch_block_t?block); ? ? ?3.9 多次執(zhí)行 ?dispatch_apply(size_t?iterations,?dispatch_queue_t?queue,void (^block)(size_t)); ? ? ?…………………等等…………………4.幾個(gè)方法參數(shù)解釋:
<1>創(chuàng)建自定義的隊(duì)列? ??dispatch_queue_create(const?char?*label,?dispatch_queue_attr_t?attr);
const?char?*label:隊(duì)列名字 ?? ? ? ? ? ? ? ? ?dispatch_queue_attr_t?attr:隊(duì)列執(zhí)行方式(串行、并行)
<2>創(chuàng)建默認(rèn)的全局隊(duì)列?dispatch_get_global_queue(long?identifier,?unsigned?long?flags)
long?identifier:隊(duì)列執(zhí)行的優(yōu)先級(jí) ? ? ? ? ??unsigned?long?flags:默認(rèn)為0即可
<3>多次執(zhí)行 ? ? ? ??dispatch_apply(size_t?iterations,?dispatch_queue_t?queue,void?(^block)(size_t));
size_t?iterations:執(zhí)行次數(shù) ? ? ?dispatch_queue_t?queue:隊(duì)列 ? ? ?void?(^block)(size_t):block函數(shù)塊
? 5.隊(duì)列方式宏定義(用于創(chuàng)建自定義隊(duì)列時(shí)的參數(shù))#define DISPATCH_QUEUE_SERIAL NULL ? ? ? ? //串行
#define DISPATCH_QUEUE_CONCURRENT ? ? ? ?//并行
?
6.隊(duì)列優(yōu)先級(jí)宏定義(創(chuàng)建全局隊(duì)列時(shí)的參數(shù))
#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.更能區(qū)分
主隊(duì)列:專門用來執(zhí)行主線程的,進(jìn)行UI的更新操作
全局隊(duì)列或自定義隊(duì)列:用來添加并執(zhí)行其他的線程,進(jìn)行數(shù)據(jù)的操作
?
?具體舉例如下:
例子1:采用不分組的方式,將多線程添加到隊(duì)列中,然后進(jìn)行多線程的操作。
1.準(zhǔn)備UI界面布局:拖入一個(gè)文本視圖控件,并關(guān)聯(lián)相關(guān)的類中,同時(shí)在類中聲明一個(gè)票數(shù)變量
@interface ViewController () {NSInteger _tickets; } @property (weak, nonatomic) IBOutlet UITextView *textView; @end2.設(shè)置票數(shù),同時(shí)將原來文本視圖中默認(rèn)的數(shù)據(jù)清空,取消自動(dòng)布局便于后面添加數(shù)據(jù)時(shí)自動(dòng)滾動(dòng)文本視圖
//設(shè)置數(shù)據(jù)和文本視圖_tickets = 20;[self.textView setText:@""];self.textView.layoutManager.allowsNonContiguousLayout = NO;3.創(chuàng)建全局隊(duì)列,并設(shè)置優(yōu)先級(jí),設(shè)置并行方式
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);4.用GCD創(chuàng)建任務(wù)線程,并將線程添加到隊(duì)列中,采用異步執(zhí)行方式
dispatch_async(queue, ^{[self GCDSellTicketMethod:@"GCD售票線程-1"];});dispatch_async(queue, ^{[self GCDSellTicketMethod:@"GCD售票線程-2"];});5.定義更新UI的方法
#pragma mark -更新UI的操作
-(void)appendTextView:(NSString *)text {//1.獲取原來的數(shù)據(jù)NSMutableString *content = [NSMutableString stringWithString:self.textView.text];NSRange range = NSMakeRange(content.length, 2);//2.追加新的內(nèi)容[content appendString:[NSString stringWithFormat:@"\n%@",text]];[self.textView setText:content];//3.滾動(dòng)視圖 [self.textView scrollRangeToVisible:range]; }6.定義任務(wù)線程的執(zhí)行方法
#pragma mark -執(zhí)行線程的操作
-(void)GCDSellTicketMethod:(NSString *)name {while (YES){if(_tickets > 0){//使用GCDdispatch_async(dispatch_get_main_queue(), ^{//更新UINSString *info = [NSString stringWithFormat:@"總票數(shù):%ld,當(dāng)前的線程:%@",_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:@"票已經(jīng)賣完,當(dāng)前線程:%@",name];[self appendTextView:info];});//退出線程break;}} }?
例子2:采用分組的方式,將線程組添加到隊(duì)列中,然后進(jìn)行多線程的操作。
1.準(zhǔn)備UI界面布局:拖入一個(gè)文本視圖控件,并關(guān)聯(lián)相關(guān)的類中,同時(shí)在類中聲明一個(gè)票數(shù)變量
@interface ViewController () {NSInteger _tickets; } @property (weak, nonatomic) IBOutlet UITextView *textView; @end2.設(shè)置票數(shù),同時(shí)將原來文本視圖中默認(rèn)的數(shù)據(jù)清空,取消自動(dòng)布局便于后面添加數(shù)據(jù)時(shí)自動(dòng)滾動(dòng)文本視圖
//設(shè)置數(shù)據(jù)和文本視圖_tickets = 20;[self.textView setText:@""];self.textView.layoutManager.allowsNonContiguousLayout = NO;3.創(chuàng)建一個(gè)線程分組
dispatch_group_t group = dispatch_group_create();4.創(chuàng)建自定義的隊(duì)列,并設(shè)置隊(duì)列執(zhí)行方式為并行方式
??dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
5.用GCD創(chuàng)建任務(wù)線程組,并將線程組添加到隊(duì)列中,采用分組異步執(zhí)行方式
? dispatch_group_async(group,queue, ^{
? ? ? [self GCDSellTicketMethod:@"GCD售票線程-1"];
? });? ?
? dispatch_group_async(group,queue, ^{
? ? ? [self GCDSellTicketMethod:@"GCD售票線程-2"];
? });
6.等線程組中的所有任務(wù)完成后,會(huì)接收到通知,更新UI
dispatch_group_notify(group, queue, ^{dispatch_async(dispatch_get_main_queue(), ^{NSString *info = [NSString stringWithFormat:@"票已經(jīng)賣完"];[self appendTextView:info];});});7.定義更新UI的方法
#pragma mark -更新UI的操作
-(void)appendTextView:(NSString *)text {//1.獲取原來的數(shù)據(jù)NSMutableString *content = [NSMutableString stringWithString:self.textView.text];NSRange range = NSMakeRange(content.length, 2);//2.追加新的內(nèi)容[content appendString:[NSString stringWithFormat:@"\n%@",text]];[self.textView setText:content];//3.滾動(dòng)視圖[self.textView scrollRangeToVisible:range]; }8.定義任務(wù)線程的執(zhí)行方法
#pragma mark -執(zhí)行線程的操作
-(void)GCDSellTicketMethod:(NSString *)name {while (YES){if(_tickets > 0){//使用GCDdispatch_async(dispatch_get_main_queue(), ^{//更新UINSString *info = [NSString stringWithFormat:@"總票數(shù):%ld,當(dāng)前的線程:%@",_tickets,name];[self appendTextView:info];//賣票_tickets--;});//線程休眠if([name isEqualToString:@"GCD售票線程-1"]){[NSThread sleepForTimeInterval:0.3f];}else{[NSThread sleepForTimeInterval:0.2f];}}else{ //退出線程break;}} }?
兩種情況的演示結(jié)果如下:
?
?
?
?
?
?
?
程序猿神奇的手,每時(shí)每刻,這雙手都在改變著世界的交互方式! 分類:?iOS高級(jí)本文轉(zhuǎn)自當(dāng)天真遇到現(xiàn)實(shí)博客園博客,原文鏈接:http://www.cnblogs.com/XYQ-208910/p/4859089.html,如需轉(zhuǎn)載請(qǐng)自行聯(lián)系原作者
總結(jié)
以上是生活随笔為你收集整理的iOS:多线程技术GCD的使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 梦到蜜蜂往身上飞预示什么
- 下一篇: socket websocket