1. 程式人生 > >iOS學習筆記-108.多執行緒07——CGD柵欄函式、延時、一次性程式碼

iOS學習筆記-108.多執行緒07——CGD柵欄函式、延時、一次性程式碼

多執行緒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 說明

我們建立四個任務。在柵欄函式前面建立兩個 ,柵欄函式後面建立兩個。我們得到的結果應該是:

  1. 先執行前面兩個任務,執行完了到第2步
  2. 執行柵欄函式,執行完了到第3步
  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------