iOS學習筆記-108.多執行緒07——CGD柵欄函式、延時、一次性程式碼
阿新 • • 發佈:2019-01-31
多執行緒07——CGD柵欄函式、延時、一次性程式碼
一、說明
1.1 柵欄函式說明
dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
在前面的任務執行結束後它才執行,除此之外只有它本身執行完了,它後面的任才能被執行
示例程式碼
dispatch_barrier_async(queue, ^{
NSLog(@"++++++++++++++++++++++++++++++");
});
1.2 延時執行
dispatch_after(dispatch_time_t when ,
dispatch_queue_t queue,
dispatch_block_t block);
可以使用已經內建的程式碼模板
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<delayInSeconds> * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
<code to be executed after a specified delay>
});
使用說明
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//2秒鐘後執行的程式碼。。。。。。
});
1.3 一次性程式碼
使用 dispatch_once 函式能保證某段程式碼在程式執行過程中只被執行1次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
// 只執行1次的程式碼(這裡面預設是執行緒安全的)
});
二、柵欄函式
2.1 說明
我們建立四個任務。在柵欄函式前面建立兩個 ,柵欄函式後面建立兩個。我們得到的結果應該是:
- 先執行前面兩個任務,執行完了到第2步
- 執行柵欄函式,執行完了到第3步
- 執行後面的兩個任務
2.2 程式碼
/*柵欄函式*/
-(void)barrier{
dispatch_queue_t queue = dispatch_queue_create("com.wiming", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
for (int i=0; i<5; i++) {
NSLog(@"download1--%zd---%@",i,[NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i=0; i<5; i++) {
NSLog(@"download2--%zd---%@",i,[NSThread currentThread]);
}
});
dispatch_barrier_async(queue, ^{
NSLog(@"++++++++++++++++++++++++++++++");
});
dispatch_async(queue, ^{
for (int i=0; i<5; i++) {
NSLog(@"download3--%zd---%@",i,[NSThread currentThread]);
}
});
dispatch_async(queue, ^{
for (int i=0; i<5; i++) {
NSLog(@"download4--%zd---%@",i,[NSThread currentThread]);
}
});
}
2.3 結果
[72846:415833] download1--0---<NSThread: 0x600000076b00>{number = 4, name = (null)}
[72846:415834] download2--0---<NSThread: 0x60800007d900>{number = 3, name = (null)}
[72846:415833] download1--1---<NSThread: 0x600000076b00>{number = 4, name = (null)}
[72846:415834] download2--1---<NSThread: 0x60800007d900>{number = 3, name = (null)}
[72846:415833] download1--2---<NSThread: 0x600000076b00>{number = 4, name = (null)}
[72846:415834] download2--2---<NSThread: 0x60800007d900>{number = 3, name = (null)}
[72846:415833] download1--3---<NSThread: 0x600000076b00>{number = 4, name = (null)}
[72846:415834] download2--3---<NSThread: 0x60800007d900>{number = 3, name = (null)}
[72846:415833] download1--4---<NSThread: 0x600000076b00>{number = 4, name = (null)}
[72846:415834] download2--4---<NSThread: 0x60800007d900>{number = 3, name = (null)}
[72846:415834] ++++++++++++++++++++++++++++++
[72846:415834] download3--0---<NSThread: 0x60800007d900>{number = 3, name = (null)}
[72846:415833] download4--0---<NSThread: 0x600000076b00>{number = 4, name = (null)}
[72846:415834] download3--1---<NSThread: 0x60800007d900>{number = 3, name = (null)}
[72846:415833] download4--1---<NSThread: 0x600000076b00>{number = 4, name = (null)}
[72846:415834] download3--2---<NSThread: 0x60800007d900>{number = 3, name = (null)}
[72846:415833] download4--2---<NSThread: 0x600000076b00>{number = 4, name = (null)}
[72846:415834] download3--3---<NSThread: 0x60800007d900>{number = 3, name = (null)}
[72846:415833] download4--3---<NSThread: 0x600000076b00>{number = 4, name = (null)}
[72846:415834] download3--4---<NSThread: 0x60800007d900>{number = 3, name = (null)}
[72846:415833] download4--4---<NSThread: 0x600000076b00>{number = 4, name = (null)}
2.4 結果分析
通過上面的結果我們可以看到
任務1和任務2(download1和download2),首先執行,它們執行完了 才執行 柵欄函式裡面的程式碼,柵欄函式裡面的程式碼執行完了 ,才開始執行任務3和任務4(download3和download4)
三、延時執行
3.1. 呼叫NSObject的方法
//第一個引數:方法選擇器,就是時間到了以後要執行的方法
//第二個引數:方法的引數
//第三個引數:延時的時長
- (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay;
示例程式碼
/*延時*/
-(void)delay{
NSLog(@"start------");
//第一種方式
[self performSelector:@selector(task) withObject:nil afterDelay:2.0];
}
-(void)task{
NSLog(@"task-------%@",[NSThread currentThread]);
}
結果
2017-09-03 01:48:42.194 03_UIview83多執行緒GCD[74790:425940] start------
2017-09-03 01:48:44.196 03_UIview83多執行緒GCD[74790:425940] task-------<NSThread: 0x608000068dc0>{number = 1, name = main}
我們可以看一下時間,確實是2s
01:48:42
01:48:44
3.2 使用NSTime
使用的方式是
+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;
示例程式碼
/*延時*/
-(void)delay{
NSLog(@"start------");
//第二種方式
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(task) userInfo:nil repeats:NO];
}
-(void)task{
NSLog(@"task-------%@",[NSThread currentThread]);
}
結果
2017-09-03 03:13:55.639 03_UIview83多執行緒GCD[77570:439579] start------
2017-09-03 03:13:57.641 03_UIview83多執行緒GCD[77570:439579] task-------<NSThread: 0x600000074d00>{number = 1, name = main}
3.3 使用GCD函式
示例程式碼
/*延時*/
-(void)delay{
NSLog(@"start------");
//GCD
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"GCD-------%@",[NSThread currentThread]);
});
}
結果
2017-09-03 03:15:57.027 03_UIview83多執行緒GCD[78003:442676] start------
2017-09-03 03:15:59.218 03_UIview83多執行緒GCD[78003:442676] GCD-------<NSThread: 0x608000066cc0>{number = 1, name = main}
四、一次性程式碼
示例程式碼
/*一次性程式碼*/
-(void)once{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"------one------");
});
}
結果 程式執行以後,無論操作多少次都只會執行一次
2017-09-03 03:19:17.991 03_UIview83多執行緒GCD[78649:447665] ------one------