Swift3 GCD大全

本文是對這篇文章中GCD的使用方法的語法翻譯

另外推薦這篇

看完以上兩篇,我保證你的GCD差不多都掌握了

  • Swift2.3與swift3.0全局隊列優先級對應關系(高 > 默認 > 低 > 后臺)
  DISPATCH_QUEUE_PRIORITY_HIGH                   .userInitiated
  DISPATCH_QUEUE_PRIORITY_DEFAULT                .default
  DISPATCH_QUEUE_PRIORITY_LOW                    .utility
  DISPATCH_QUEUE_PRIORITY_BACKGROUND             .background

修條環城路(創建一個子線程)

        // Swift2.3
        let queue = dispatch_queue_create("環城路", nil)
        // 異步執行
        dispatch_async(queue) {
           // 給碴土車走的(耗時操作) 
        }

        // Swift3.0
        DispatchQueue(label: "環城路").async {
            // 給碴土車走的(耗時操作)
        }

走城市自帶的環城(使用全局隊列)

        // Swift2.3
      //高 > 默認 > 低 > 后臺
        let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
    //  DISPATCH_QUEUE_PRIORITY_HIGH
    //  DISPATCH_QUEUE_PRIORITY_DEFAULT           
    //  DISPATCH_QUEUE_PRIORITY_LOW
    //  DISPATCH_QUEUE_PRIORITY_BACKGROUND
      
        let queue = dispatch_get_global_queue(priority, 0)
        // 異步執行
        dispatch_async(queue) {
           // 給碴土車走的(耗時操作) 
        }

        // Swift3.0
      let qos: DispatchQoS.QoSClass =  .default 
      // .userInitiated > .default > .utility > .background
       
       DispatchQueue.global(qos:  qos).async {
            // 給碴土車走的(耗時操作)
        }

同步執行串行隊列

         // Swift2.3
        let queue = dispatch_queue_create("syn.serial.queue", DISPATCH_QUEUE_SERIAL)
        for i in 0..<3 {
            dispatch_sync(queue) {
                currentThreadSleep(1)
                print("當前執行線程:\(getCurrentThread())")
                print("執行\(i)")
            }
            print("\(i)執行完畢")
        }
    print("所有隊列使用同步方式執行完畢")

        // Swift3.0
       for i in 0..<3 {
            DispatchQueue(label: "syn.serial.queue").sync() {
                currentThreadSleep(1)
                print("當前執行線程:\(Thread.current)")
                print("執行\(i.toEmoji)")
            }
            print("\(i.toEmoji)執行完畢")
        }
屏幕快照 2016-11-29 上午10.08.22.png

同步執行并行隊列

        // Swift2.3
    let queue = dispatch_queue_create("syn.concurrent.queue", DISPATCH_QUEUE_CONCURRENT)
        for i in 0..<3 {
            dispatch_sync(queue) {
                currentThreadSleep(1)
                print("當前執行線程:\(getCurrentThread())")
                print("執行\(i)")
            }
          print("\(i)執行完畢")
        }
        print("所有隊列使用同步方式執行完畢")


        // Swift3.0
        for i in 0..<3 {
            DispatchQueue(label: "syn.concurrent.queue", attributes: .concurrent).sync() {
                currentThreadSleep(1)
                print("當前執行線程:\(Thread.current)")
                print("執行\(i.toEmoji)")
            }
            print("\(i.toEmoji)執行完畢")
        }
屏幕快照 2016-11-29 上午10.10.55.png

異步執行串行隊列

  // Swift2.3
    let serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL)
    let queue = dispatch_queue_create("asyn.serial.queue", DISPATCH_QUEUE_SERIAL)
    
    for i in 0..<3 {
        dispatch_async(queue) {
            currentThreadSleep(Double(arc4random()%3))
            let currentThread = getCurrentThread()
            
            dispatch_sync(serialQueue, {              //同步鎖
                print("Sleep的線程\(currentThread)")
                print("當前輸出內容的線程\(getCurrentThread())")
                print("執行\(i):\(queue)\n")
            })
        }
        
        print("\(i)添加完畢\n")
    }
    print("使用異步方式添加隊列")


  // Swift3.0 
   let serialQueue = DispatchQueue(label: "serialQueue")
        for i in 0..<3 {
            group.enter()
            DispatchQueue(label: "asyn.serial.queue").async(group: group) {
                self.currentThreadSleep(Double(arc4random()%3))
                let currentThread = Thread.current
                serialQueue.sync {              //同步鎖
                    group.leave()
                    print("①Sleep的線程\(currentThread)")
                    print("②當前輸出內容的線程\(Thread.current)")
                    print("③執行\(i.toEmoji):\(queue)\n")
                }
            }
            print("\(i.toEmoji)添加完畢\n")
        }
屏幕快照 2016-11-29 上午10.21.13.png

異步執行并行隊列

 // Swift2.3
    let serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL)
    let queue = dispatch_queue_create("asyn.concurrent.queue", DISPATCH_QUEUE_CONCURRENT)
    for i in 0..<3 {
        dispatch_async(queue) {
            currentThreadSleep(Double(arc4random()%3))
            let currentThread = getCurrentThread()
            
            dispatch_sync(serialQueue, {              //同步鎖
                print("Sleep的線程\(currentThread)")
                print("當前輸出內容的線程\(getCurrentThread())")
                print("執行\(i):\(queue)\n")
            })
        }
        
        print("\(i)添加完畢\n")
    }
    print("使用異步方式添加隊列")

// Swift3.0 
    let serialQueue = DispatchQueue(label: "serialQueue")
        for i in 0..<3 {
            group.enter()
            DispatchQueue(label: "asyn.concurrent.queue", attributes: .concurrent).async(group: group) {
                self.currentThreadSleep(Double(arc4random()%3))
                let currentThread = Thread.current
                serialQueue.sync {              //同步鎖
                    group.leave()
                    print("①Sleep的線程\(currentThread)")
                    print("②當前輸出內容的線程\(Thread.current)")
                    print("③執行\(i.toEmoji):\(queue)\n")
                }
            }
            print("\(i.toEmoji)添加完畢\n")
        }
        print("使用異步方式添加隊列")
屏幕快照 2016-11-29 上午10.37.35.png

延遲執行

     // Swift2.3
    //dispatch_time用于計算相對時間,當設備睡眠時,dispatch_time也就跟著睡眠了
    let delayTime: dispatch_time_t = dispatch_time(DISPATCH_TIME_NOW, Int64(time * Double(NSEC_PER_SEC)))
    dispatch_after(delayTime, getGlobalQueue()) {
        print("執行線程:\(getCurrentThread())\ndispatch_time: 延遲\(time)秒執行\n")
    }
    
    //dispatch_walltime用于計算絕對時間,而dispatch_walltime是根據掛鐘來計算的時間,即使設備睡眠了,他也不會睡眠。
    let nowInterval = NSDate().timeIntervalSince1970
    var nowStruct = timespec(tv_sec: Int(nowInterval), tv_nsec: 0)
    let delayWalltime = dispatch_walltime(&nowStruct, Int64(time * Double(NSEC_PER_SEC)))
    dispatch_after(delayWalltime, getGlobalQueue()) {
        print("執行線程:\(getCurrentThread())\ndispatch_walltime: 延遲\(time)秒執行\n")
    }

    // Swift3.0 

        let semaphore = DispatchSemaphore(value: 0)
        let queue = getGlobalQueue()
        let delaySecond = DispatchTimeInterval.seconds(time)
        
        print(Date())
        let delayTime = DispatchTime.now() + delaySecond
        queue.asyncAfter(deadline: delayTime) {
            print("執行線程:\(Thread.current)\ndispatch_time: 延遲\(time)秒執行\n",Date())
            semaphore.signal()
        }
        
        //DispatchWallTime用于計算絕對時間,而DispatchWallTime是根據掛鐘來計算的時間,即使設備睡眠了,他也不會睡眠。
//        let nowInterval = Date().timeIntervalSince1970
//        let nowStruct = timespec(tv_sec: Int(nowInterval), tv_nsec: 0)
//        let delayWalltime = DispatchWallTime(timespec: nowStruct)
        let delayWalltime = DispatchWallTime.now() + delaySecond
        queue.asyncAfter(wallDeadline: delayWalltime) {
            print("執行線程:\(Thread.current)\ndispatch_walltime: 延遲\(time)秒執行\n", Date())
        }
        semaphore.wait()
屏幕快照 2016-11-29 上午10.48.21.png

設置全局隊列的優先級

 // Swift2.3
    let queueHeight: dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)
    let queueDefault: dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
    let queueLow: dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0)
    let queueBackground: dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0)
   
    
    //優先級不是絕對的,大體上會按這個優先級來執行。 一般都是使用默認(default)優先級
    dispatch_async(queueLow) {
        print("Low:\(getCurrentThread())")
    }
    
    dispatch_async(queueBackground) {
        print("Background:\(getCurrentThread())")
    }
    
    dispatch_async(queueDefault) {
        print("Default:\(getCurrentThread())")
    }
    
    dispatch_async(queueHeight) {
        print("High:\(getCurrentThread())")
    }

// Swift3.0

        let queueHeight = DispatchQueue.global(qos: .userInitiated)
        let queueDefault = DispatchQueue.global(qos: .default)
        let queueLow = DispatchQueue.global(qos: .utility)
        let queueBackground = DispatchQueue.global(qos: .background)
        
        let group = DispatchGroup()
        //優先級不是絕對的,大體上會按這個優先級來執行。 一般都是使用默認(default)優先級
        queueLow.async(group: group) {
            
            print("Low:\(Thread.current)")
        }
        
        queueBackground.async(group: group) {
            print("Background:\(Thread.current)")
        }
        
        queueDefault.async(group: group) {
            print("Default:\(Thread.current)")
        }
        
        queueHeight.async(group: group) {
            print("High:\(Thread.current)")
        }
屏幕快照 2016-11-29 上午10.54.46.png

設置自建隊列優先級

 // Swift2.3

    //優先級的執行順序也不是絕對的
    
    //給serialQueueHigh設定DISPATCH_QUEUE_PRIORITY_HIGH優先級
    let serialQueueHigh = getSerialQueue("cn.zeluli.serial1")
    dispatch_set_target_queue(serialQueueHigh, getGlobalQueue(DISPATCH_QUEUE_PRIORITY_HIGH))
    
    let serialQueueLow = getSerialQueue("cn.zeluli.serial1")
    dispatch_set_target_queue(serialQueueLow, getGlobalQueue(DISPATCH_QUEUE_PRIORITY_LOW))
    
    
    dispatch_async(serialQueueLow) {
        print("低:\(getCurrentThread())")
    }
    
    dispatch_async(serialQueueHigh) {
        print("高:\(getCurrentThread())")
    }

// Swift3.0

        //優先級的執行順序也不是絕對的
        
        //給serialQueueHigh設定DISPATCH_QUEUE_PRIORITY_HIGH優先級
        let serialQueueHigh = DispatchQueue(label: "cn.zeluli.serial1")
        DispatchQueue.global(qos: .userInitiated).setTarget(queue: serialQueueHigh)
        
        let serialQueueLow = DispatchQueue(label: "cn.zeluli.serial1")
        DispatchQueue.global(qos: .utility).setTarget(queue: serialQueueLow)
        
        serialQueueLow.async {
            print("低:\(Thread.current)")
        }
        
        serialQueueHigh.async {
            print("高:\(Thread.current)")
            self.ended()
        }
屏幕快照 2016-11-29 上午10.59.55.png

自動執行任務組

// Swift2.3
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { 
        let concurrentQueue: dispatch_queue_t = getConcurrentQueue("cn.zeluli")
        let group: dispatch_group_t = dispatch_group_create()
        
        //將group與queue進行管理,并且自動執行
        for i in 1...3 {
            dispatch_group_async(group, concurrentQueue) {
                currentThreadSleep(1)
                print("任務\(i)執行完畢\n")
            }
        }
        
        //隊列組的都執行完畢后會進行通知
        dispatch_group_notify(group, dispatch_get_main_queue()) {
            print("所有的任務組執行完畢!\n")
        }
        
        print("異步執行測試,不會阻塞當前線程")
    }

// Swift3.0
        DispatchQueue.global(qos: .default).async {
            let concurrentQueue = DispatchQueue(label: "cn.zeluli", attributes: .concurrent)
            let group = DispatchGroup()
            
            //將group與queue進行管理,并且自動執行
            for i in 1...3 {
                concurrentQueue.async(group: group) {
                    self.currentThreadSleep(1)
                    print("任務\(i)執行完畢\n")
                }
            }
            
            //隊列組的都執行完畢后會進行通知
            group.notify(queue: DispatchQueue.main) {
                self.ended()
            }
            
            print("異步執行測試,不會阻塞當前線程")
        }
屏幕快照 2016-11-29 上午11.06.37.png

手動執行任務組

// Swift2.3
    let concurrentQueue: dispatch_queue_t = dispatch_queue_create("cn.zeluli", DISPATCH_QUEUE_CONCURRENT)
    let group: dispatch_group_t = dispatch_group_create()
    
    //將group與queue進行手動關聯和管理,并且自動執行
    for i in 1...3 {
        dispatch_group_enter(group)                     //進入隊列組
        
        dispatch_async(concurrentQueue, {
            currentThreadSleep(1)
            print("任務\(i)執行完畢\n")
            
            dispatch_group_leave(group)                 //離開隊列組
        })
    }
    
    dispatch_group_wait(group, DISPATCH_TIME_FOREVER)   //阻塞當前線程,直到所有任務執行完畢
    print("任務組執行完畢")
    
    dispatch_group_notify(group, concurrentQueue) {
        print("手動管理的隊列執行OK")
    }

// Swift3.0
        let concurrentQueue = DispatchQueue(label: "cn.zeluli", attributes: .concurrent)
        let group = DispatchGroup()
        
        //將group與queue進行手動關聯和管理,并且自動執行
        for i in 1...3 {
            group.enter() //進入隊列組
            concurrentQueue.async {
                self.currentThreadSleep(1)
                print("任務\(i.toEmoji)執行完畢\n")
                group.leave()                 //離開隊列組
            }
        }
        
        _ = group.wait(timeout: .distantFuture) //阻塞當前線程,直到所有任務執行完畢
        print("任務組執行完畢")
        
        group.notify(queue: concurrentQueue) {
            self.ended()
        }
屏幕快照 2016-11-29 上午11.10.19.png

使用信號量添加同步鎖

// Swift2.3
func useSemaphoreLock() {
    
    let concurrentQueue = getConcurrentQueue("cn.zeluli")
    
    //創建信號量
    let semaphoreLock: dispatch_semaphore_t = dispatch_semaphore_create(1)
    
    var testNumber = 0
    
    for index in 1...10 {
        dispatch_async(concurrentQueue, {
            dispatch_semaphore_wait(semaphoreLock, DISPATCH_TIME_FOREVER) //上鎖
            
            testNumber += 1
            currentThreadSleep(Double(1))
            print(getCurrentThread())
            print("第\(index)次執行: testNumber = \(testNumber)\n")
            
            dispatch_semaphore_signal(semaphoreLock)                      //開鎖
            
        })
    }
    
    print("異步執行測試\n")
}

// Swift3.0
func useSemaphoreLock() {
        
        let concurrentQueue = getConcurrentQueue("cn.zeluli")
        
        //創建信號量
        let semaphoreLock = DispatchSemaphore(value: 1)
        
        var testNumber = 0
        
        for index in 0...9 {
            concurrentQueue.async {
                let wait = semaphoreLock.wait(timeout: .distantFuture) //上鎖
                print("wait=\(wait)")
                testNumber += 1
                self.currentThreadSleep(1)
                print(Thread.current)
                print("第\(index.toEmoji)次執行: testNumber = \(testNumber)\n")
                
                semaphoreLock.signal()                      //開鎖
                
            }
        }
    }
屏幕快照 2017-02-17 下午4.42.35.png

使用Apply循環執行

// Swift2.3
func useDispatchApply() {
    
    print("循環多次執行并行隊列")
    let concurrentQueue: dispatch_queue_t = getConcurrentQueue("cn.zeluli")
    //會阻塞當前線程, 但concurrentQueue隊列會在新的線程中執行
    dispatch_apply(3, concurrentQueue) { (index) in
        
        currentThreadSleep(Double(index))
        print("第\(index)次執行,\n\(getCurrentThread())\n")
    }
    
    
    
    print("\n\n循環多次執行串行隊列")
    let serialQueue: dispatch_queue_t = getSerialQueue("cn.zeluli")
    //會阻塞當前線程, serialQueue隊列在當前線程中執行
    dispatch_apply(3, serialQueue) { (index) in
        
        currentThreadSleep(Double(index))
        print("第\(index)次執行,\n\(getCurrentThread())\n")
    }
}

// Swift3.0
/// 循環執行
    func useDispatchApply() {
        
        print("循環多次執行并行隊列")

        DispatchQueue.concurrentPerform(iterations: 3) { (index) in
            currentThreadSleep(Double(index))
            print("第\(index)次執行,\n\(Thread.current)\n")
        }
        ended()
   }
屏幕快照 2017-02-17 下午4.50.14.png

暫停和重啟隊列

// Swift2.3
func queueSuspendAndResume() {
    let concurrentQueue = getConcurrentQueue("cn.zeluli")
    
    dispatch_suspend(concurrentQueue)   //將隊列進行掛起
    dispatch_async(concurrentQueue) { 
        print("任務執行")
    }
    
    currentThreadSleep(2)
    dispatch_resume(concurrentQueue)    //將掛起的隊列進行喚醒
}

// Swift3.0
func queueSuspendAndResume() {
        let concurrentQueue = getConcurrentQueue("cn.zeluli")
        concurrentQueue.suspend()   //將隊列進行掛起
        concurrentQueue.async { 
            print("任務執行, \(Thread.current)")
        }
        
        currentThreadSleep(2)
        concurrentQueue.resume()    //將掛起的隊列進行喚醒
        ended()
    }

使用任務隔離柵欄(這個東西可以用來處理經典的數組異步讀寫問題)

// Swift2.3
func useBarrierAsync() {
    let concurrentQueue: dispatch_queue_t = getConcurrentQueue("cn.zeluli")
    for i in 0...3 {
        dispatch_async(concurrentQueue) {
            currentThreadSleep(Double(i))
            print("第一批:\(i)\(getCurrentThread())")
        }
    }
    
    
    dispatch_barrier_async(concurrentQueue) {

        print("\n第一批執行完畢后才會執行第二批\n\(getCurrentThread())\n")
    }
    
    
    for i in 0...3 {
        dispatch_async(concurrentQueue) {
            currentThreadSleep(Double(i))
            print("第二批:\(i)\(getCurrentThread())")
        }
    }
    
    print("異步執行測試\n")
}


// Swift3.0
func useBarrierAsync() {
        
        
        let concurrentQueue = getConcurrentQueue("cn.zeluli")
        for i in 0...3 {
            concurrentQueue.async {
                self.currentThreadSleep(Double(i))
                print("第一批:\(i.toEmoji)\(Thread.current)")
            }
        }
        
        let workItem = DispatchWorkItem(flags: .barrier) {
            print("\n第一批執行完畢后才會執行第二批\n\(Thread.current)\n")
        }
        
        concurrentQueue.async(execute: workItem)
        
        
        for i in 0...3 {
            concurrentQueue.async {
                self.currentThreadSleep(Double(i))
                print("第二批:\(i.toEmoji)\(Thread.current)")
            }
        }
        
        print("??????不會阻塞主線程??????")
    }
屏幕快照 2017-02-17 下午4.59.47.png

DispatchSource

// Swift2.3
/**
 以加法運算的方式合并數據
 */
func useDispatchSourceAdd() {
    var sum = 0     //手動計數的sum, 來模擬記錄merge的數據
    
    let queue = getGlobalQueue()
    
    //創建source
    let dispatchSource:dispatch_source_t = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, queue)
    
    dispatch_source_set_event_handler(dispatchSource) {
        print("source中所有的數相加的和等于\(dispatch_source_get_data(dispatchSource))")
        print("sum = \(sum)\n")
        sum = 0
       currentThreadSleep(0.3)
    }

    dispatch_resume(dispatchSource)
    
    for i in 1...10 {
        sum += i
        print(i)
        dispatch_source_merge_data(dispatchSource, UInt(i))
        currentThreadSleep(0.1)
    }
}


/**
 以或運算的方式合并數據
 */
func useDispatchSourceOr() {
    
    var or = 0     //手動計數的sum, 來記錄merge的數據
    
    let queue = getGlobalQueue()
    
    //創建source
    let dispatchSource:dispatch_source_t = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_OR, 0, 0, queue)
    
    dispatch_source_set_event_handler(dispatchSource) {
        print("source中所有的數相加的和等于\(dispatch_source_get_data(dispatchSource))")
        print("or = \(or)\n")
        or = 0
        currentThreadSleep(0.3)
        
    }
    
    dispatch_resume(dispatchSource)
    
    for i in 1...10 {
        or |= i
        print(i)
        dispatch_source_merge_data(dispatchSource, UInt(i))
        
        currentThreadSleep(0.1)
        
    }
    
    print("\nsum = \(or)")
}

/**
 使用dispatch_source創建定時器
 */
func useDispatchSourceTimer() {
    let queue: dispatch_queue_t = getGlobalQueue()
    let source: dispatch_source_t = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue)
   
    //設置間隔時間,從當前時間開始,允許偏差0納秒
    dispatch_source_set_timer(source, DISPATCH_TIME_NOW, UInt64(1 * NSEC_PER_SEC), 0)
    
    var timeout = 10    //倒計時時間
    
    //設置要處理的事件, 在我們上面創建的queue隊列中進行執行
    dispatch_source_set_event_handler(source) {
        print(getCurrentThread())
        if(timeout <= 0) {
            dispatch_source_cancel(source)
        } else {
            print("\(timeout)s")
            timeout -= 1
        }
    }
    
    //倒計時結束的事件
    dispatch_source_set_cancel_handler(source) { 
        print("倒計時結束")
    }
    dispatch_resume(source)
}

// Swift3.0
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px 'PingFang SC'; color: #4dbf56}p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo; color: #526eda}p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo; color: #ffffff}p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo; color: #4dbf56}p.p5 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo; color: #ffffff; min-height: 21.0px}p.p6 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo; color: #93c96a}p.p7 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px Menlo; color: #00afca}span.s1 {font: 18.0px Menlo; font-variant-ligatures: no-common-ligatures}span.s2 {font-variant-ligatures: no-common-ligatures}span.s3 {font-variant-ligatures: no-common-ligatures; color: #ffffff}span.s4 {font-variant-ligatures: no-common-ligatures; color: #4dbf56}span.s5 {font-variant-ligatures: no-common-ligatures; color: #526eda}span.s6 {font-variant-ligatures: no-common-ligatures; color: #c2349b}span.s7 {font-variant-ligatures: no-common-ligatures; color: #8b84cf}span.s8 {font: 18.0px 'PingFang SC'; font-variant-ligatures: no-common-ligatures}span.s9 {font-variant-ligatures: no-common-ligatures; color: #93c96a}span.s10 {font-variant-ligatures: no-common-ligatures; color: #00afca}span.s11 {font-variant-ligatures: no-common-ligatures; color: #e44347}span.s12 {font: 18.0px 'PingFang SC'; font-variant-ligatures: no-common-ligatures; color: #e44347}span.s13 {font: 18.0px Menlo; font-variant-ligatures: no-common-ligatures; color: #ffffff}span.s14 {font: 18.0px 'PingFang SC'; font-variant-ligatures: no-common-ligatures; color: #4dbf56}

/// 以加法運算的方式合并數據
    // http://www.tanhao.me/pieces/360.html/
    func useDispatchSourceAdd() {
        var sum = 0     //手動計數的sum, 來模擬記錄merge的數據
        
        let queue = getGlobalQueue()
        //創建source
        let dispatchSource = DispatchSource.makeUserDataAddSource(queue: queue)
        
        dispatchSource.setEventHandler() {
            print("source中所有的數相加的和等于\(dispatchSource.data)")
            print("sum = \(sum)\n")
            sum = 0
            self.currentThreadSleep(0.3)
        }
        
        // DispatchQueue啟動時默認狀態是掛起的,創建完畢之后得主動恢復,否則事件不會被傳送
        dispatchSource.resume()
        
        for i in 1...10 {
            sum += i
            print("i=\(i)")
            dispatchSource.add(data: UInt(i))
            currentThreadSleep(0.1)
        }
        ended()
    }
    
    
    /// 以或運算的方式合并數據
    func useDispatchSourceOr() {
        
        var or = 0     //手動計數的sum, 來記錄merge的數據
        
        let queue = getGlobalQueue()
        
        //創建source
        let dispatchSource = DispatchSource.makeUserDataOrSource(queue: queue)
        
        dispatchSource.setEventHandler {
            print("source中所有的數相加的和等于\(dispatchSource.data)")
            print("or = \(or)\n")
            or = 0
            self.currentThreadSleep(0.3)
        }
        
        dispatchSource.resume()
        
        for i in 1...10 {
            or |= i
            print("i=\(i)")
            dispatchSource.or(data: UInt(i))
            currentThreadSleep(0.1)
        }
        
        print("\nsum = \(or)")
    }
    
    
    /// 使用DispatchSource創建定時器
    func useDispatchSourceTimer() {
        let queue = getGlobalQueue()
        
        let source = DispatchSource.makeTimerSource(queue: queue)
        
        // deadline 結束時間
        // interval 時間間隔
        // leeway  時間精度
        source.scheduleRepeating(deadline: .now(), interval: 1, leeway: .nanoseconds(0))

        var timeout = 10    //倒計時時間
        
        //設置要處理的事件, 在我們上面創建的queue隊列中進行執行
        
        source.setEventHandler {
            print(Thread.current)
            if(timeout <= 0) {
                source.cancel()
            } else {
                print("\(timeout)s", Date())
                timeout -= 1
            }
        }
        //倒計時結束的事件
        source.setCancelHandler {
            print("倒計時結束")
        }
        source.resume()
    }

Demo

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,362評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,577評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,486評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,852評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,600評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,944評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,944評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,108評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,652評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,385評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,616評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,111評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,798評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,205評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,537評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,334評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,570評論 2 379

推薦閱讀更多精彩內容