之前總結(jié)過(guò)很多GCD的用法,好久沒(méi)用了,這次再總結(jié)一下.做個(gè)筆記.個(gè)人理解,歡迎交流....
void dispatch_barrier_async( dispatch_queue_t queue, dispatch_block_t block);
文檔解釋:Submits a barrier block for asynchronous execution and returns immediately.
就是這個(gè)函數(shù)提交一個(gè)比較耗時(shí)的代碼塊 到一個(gè)異步操作上,并立即返回.我理解這就是異步操作.
Discussion 詳細(xì)說(shuō)明
Calls to this function always return immediately after the block has been submitted and never wait for the block to be invoked.
我理解就是 提交代碼塊以后,不做任何等待,直接返回.也就是異步.
When the barrier block reaches the front of a private concurrent queue, it is not executed immediately.
當(dāng)這個(gè)代碼塊被提交到 一個(gè)私有的并發(fā)隊(duì)列上的時(shí)候,代碼塊不會(huì)被理解執(zhí)行.
Instead, the queue waits until its currently executing blocks finish executing.
相應(yīng)的是等到這個(gè)隊(duì)列當(dāng)前正在執(zhí)行的代碼塊執(zhí)行完畢以后,才會(huì)執(zhí)行.
At that point, the barrier block executes by itself. Any blocks submitted after the barrier block are not executed until the barrier block completes.
同樣的,在這個(gè)阻塞的代碼塊之后 提交到這個(gè)隊(duì)列上的代碼塊 都不會(huì)被執(zhí)行,直到這個(gè)阻塞的代碼塊執(zhí)行完.
但是這里有個(gè)問(wèn)題:
The queue you specify should be a concurrent queue that you create yourself using the dispatch_queue_create function. If the queue you pass to this function is a serial queue or one of the global concurrent queues, this function behaves like the dispatch_async function.
調(diào)用這個(gè)方法,傳遞的queue 隊(duì)列,需要指定一個(gè)并發(fā)隊(duì)列,并且是 用 dispatch_queue_create 這個(gè)函數(shù)創(chuàng)建的.
否則,如果傳遞的隊(duì)列是一個(gè)串行的隊(duì)列,或者是一個(gè)全局的并發(fā)隊(duì)列.那么這個(gè)函數(shù)的使用效果,就是和一個(gè)簡(jiǎn)單的異步dispatch_async函數(shù)效果一樣了.
看下面代碼傳遞 一個(gè)私有的并發(fā)隊(duì)列:
let currentQueue:dispatch_queue_t = dispatch_queue_create("com.eric", DISPATCH_QUEUE_CONCURRENT);
var num = 10
dispatch_barrier_async(currentQueue) {
sleep(1)
num = 11
print(num)
print(NSThread.currentThread())
}
dispatch_barrier_async(currentQueue) {
num = 12
print(num)
print(NSThread.currentThread())
}
dispatch_barrier_async(currentQueue) {
num = 13
print(num)
print(NSThread.currentThread())
}
dispatch_barrier_async(currentQueue) {
num = 14
print(num)
print(NSThread.currentThread())
}
dispatch_barrier_async(currentQueue) {
print("5")
print(NSThread.currentThread())
}
dispatch_barrier_async(currentQueue) {
print("6")
print(NSThread.currentThread())
}
print("結(jié)束")
打印結(jié)果:
<pre>結(jié)束
11
<NSThread: 0x12cd1ee80>{number = 2, name = (null)}
12
<NSThread: 0x12cd1ee80>{number = 2, name = (null)}
13
<NSThread: 0x12cd1ee80>{number = 2, name = (null)}
14
<NSThread: 0x12cd1ee80>{number = 2, name = (null)}
5
<NSThread: 0x12cd1ee80>{number = 2, name = (null)}
6
<NSThread: 0x12cd1ee80>{number = 2, name = (null)}</pre>
說(shuō)明是異步執(zhí)行,其次在第一個(gè) dispatch_barrier_async(currentQueue) { }中添加sleep()阻塞了線程,后面的 dispatch_barrier_async(currentQueue) {}方法全部被阻塞住了.因?yàn)槲覀儌鬟f的參數(shù)是我們自己創(chuàng)建的一個(gè)私有隊(duì)列.
但是如果我們傳遞的queue是其它的,上面提到的全局并發(fā)隊(duì)列或者串行化隊(duì)列看下代碼:
let currentQueue:dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
var num = 10
dispatch_barrier_async(currentQueue) {
sleep(1)
num = 11
print(num)
print(NSThread.currentThread())
}
dispatch_barrier_async(currentQueue) {
num = 12
print(num)
print(NSThread.currentThread())
}
dispatch_barrier_async(currentQueue) {
num = 13
print(num)
print(NSThread.currentThread())
}
dispatch_barrier_async(currentQueue) {
num = 14
print(num)
print(NSThread.currentThread())
}
dispatch_barrier_async(currentQueue) {
print("5")
print(NSThread.currentThread())
}
dispatch_barrier_async(currentQueue) {
print("6")
print(NSThread.currentThread())
}
print("結(jié)束")
執(zhí)行結(jié)果:
<pre>結(jié)束
14
14
14
5
6
<NSThread: 0x12de57f80>{number = 3, name = (null)}
<NSThread: 0x12de16800>{number = 2, name = (null)}
<NSThread: 0x12de5b4b0>{number = 4, name = (null)}
<NSThread: 0x12de5dde0>{number = 5, name = (null)}
<NSThread: 0x12de512c0>{number = 6, name = (null)}
11
<NSThread: 0x12de2bfd0>{number = 7, name = (null)}
</pre>
很明顯可以看到每個(gè) dispatch_barrier_async(currentQueue) {}柵欄函數(shù),都是一個(gè)異步函數(shù).執(zhí)行的打印也交叉出現(xiàn).讀取的num值,也并不是我們想要的.出現(xiàn)數(shù)據(jù)亂竄的現(xiàn)象.</pre>
下面是提交到串行化隊(duì)列的代碼:
let currentQueue:dispatch_queue_t = dispatch_queue_create("com.eric", DISPATCH_QUEUE_SERIAL);
//let currentQueue:dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
var num = 10
dispatch_barrier_async(currentQueue) {
sleep(5)
num = 11
print(num)
print(NSThread.currentThread())
}
dispatch_barrier_async(currentQueue) {
num = 12
print(num)
print(NSThread.currentThread())
}
dispatch_barrier_async(currentQueue) {
num = 13
print(num)
print(NSThread.currentThread())
}
dispatch_barrier_async(currentQueue) {
num = 14
print(num)
print(NSThread.currentThread())
}
dispatch_barrier_async(currentQueue) {
print("5")
print(NSThread.currentThread())
}
dispatch_barrier_async(currentQueue) {
print("6")
print(NSThread.currentThread())
}
print("結(jié)束")
輸出結(jié)果:
<pre>結(jié)束
11
<NSThread: 0x15f524d40>{number = 2, name = (null)}
12
<NSThread: 0x15f524d40>{number = 2, name = (null)}
13
<NSThread: 0x15f524d40>{number = 2, name = (null)}
14
<NSThread: 0x15f524d40>{number = 2, name = (null)}
5
<NSThread: 0x15f524d40>{number = 2, name = (null)}
6
<NSThread: 0x15f524d40>{number = 2, name = (null)}</pre>
說(shuō)明:可以看出確實(shí)是順序執(zhí)行的,是串行化隊(duì)列.因?yàn)槲覀兲峤淮a塊的隊(duì)列是一個(gè)串行化的隊(duì)列.按照上文提到執(zhí)行結(jié)果和下面代碼效果一樣
dispatch_barrier_async(currentQueue) {
print("6")
print(NSThread.currentThread())
}
當(dāng)提交的隊(duì)列是串行隊(duì)列的時(shí)候, 下面的可以替換上面的
dispatch_async(currentQueue) {
print("6")
print(NSThread.currentThread())
}