iOS Dispatch swift GCD

2019-06-19  本文已影响0人  waaccv5

iOS GCD Dispatch swift

Framework Dispatch
Execute code concurrently on multicore hardware by submitting work to dispatch queues managed by the system.

import Dispatch.base         
import Dispatch.block        
import Dispatch.data         
import Dispatch.group
import Dispatch.io
import Dispatch.object
import Dispatch.once        
import Dispatch.queue
import Dispatch.semaphore
import Dispatch.source
import Dispatch.time
import Dispatch
import os_object

父类 2 3 4
NSObject OS_object DispatchObject DispatchQueue
DispatchGroup
DispatchSource
DispatchWorkItem
// 在 swift3.0 中新加的, OS_object 继承自 NSObject
// 在 GCD 中所有的对象都间接的继承自 NSObject。
import os_object
open class OS_object : NSObject {
}

1.DispatchQueue

class DispatchQueue: DispatchObject

⭑⭑⭑⭑ Important

Attempting to synchronously execute a work item on the main queue results in deadlock.

主线程同步派发一个block任务产生死锁的问题

主队列是串行队列,执行同步派发(dispatch_sync)时将等待其派发的block任务执行完毕后再返回,即不是立即返回,阻塞在此。 而block任务由于处在串行队列中,需要等前面派发的代码执行完毕才能执行,形成死锁

并发队列 串行队列(非主队列) 主队列(只有主线程,串行队列)
同步 不开启新的线程,串行 不开启新的线程,串行 不开启新的线程,串行
异步 开启新的线程,并发 开启新的线程,串行 不开启新的线程,串行
队列决定了是并行还是串行,同步异步决定了是否开启新的线程:  
即便你是串行队列,但是是异步执行,所以会启用新的线程。

1.1 Creating a Dispatch Queue 初始化

class var main: DispatchQueue
//The dispatch queue associated with the main thread of the current process.
class func global(qos: DispatchQoS.QoSClass) -> DispatchQueue  
// Returns the global system queue with the specified quality-of-service class.
init(label: String, qos: DispatchQoS, attributes: DispatchQueue.Attributes, autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency, target: DispatchQueue?)
//Creates a new dispatch queue to which you can submit blocks.

In swift, there is not.serialattribute anymore, but dispatch queues are by default serial, unless you specify the .concurrent attribute:

//串行对列
let serialQueue = DispatchQueue(label: "label") 
//并发对列
let concurrentQueue = DispatchQueue(label: "label", attributes: .concurrent) 
class OS_dispatch_queue_main
//A system-provided dispatch queue that schedules tasks for serial execution on the app's main thread.

class OS_dispatch_queue_global
//A system-provided dispatch queue that schedules tasks for concurrent execution.

class OS_dispatch_queue_serial
//A custom dispatch queue that schedules tasks for serial execution on an arbitrary thread.

class OS_dispatch_queue_concurrent
//A custom dispatch queue that schedules tasks for concurrent execution.

1.2 Executing Tasks Asynchronously 执行异步任务

func async(execute: DispatchWorkItem)
//Schedules a work item for immediate execution, and returns immediately.

func asyncAfter(deadline: DispatchTime, execute: DispatchWorkItem)
///Schedules a work item for execution at the specified time, and returns immediately.

func asyncAfter(deadline: DispatchTime, qos: DispatchQoS, flags: DispatchWorkItemFlags, execute: () -> Void)
//Schedules a block for execution using the specified attributes, and returns immediately.

func asyncAfter(wallDeadline: DispatchWallTime, execute: DispatchWorkItem)
//Schedules a work item for execution after the specified time, and returns immediately.

func asyncAfter(wallDeadline: DispatchWallTime, qos: DispatchQoS, flags: DispatchWorkItemFlags, execute: () -> Void)
//Schedules a block for execution using the specified attributes, and returns immediately.

1.3 Executing Tasks Synchronously执行同步任务

func sync(execute: DispatchWorkItem)
//Submits a work item for execution on the current queue and returns after that block finishes executing.

func sync(execute: () -> Void)
//Submits a block object for execution and returns after that block finishes executing.

func sync<T>(execute: () -> T) -> T
//Submits a work item for execution and returns the results from that item after it finishes executing.

func sync<T>(flags: DispatchWorkItemFlags, execute: () -> T) -> T
//Submits a work item for execution using the specified attributes and returns the results from that item after it finishes executing.

1.4 Executing a Task in Parallel 并行执行任务

class func concurrentPerform(iterations: Int, execute: (Int) -> Void)
//Submits a single block to the dispatch queue and causes the block to be executed the specified number of times.

1.5 Dispatching Work to Groups 隐式往Group中添加任务 (同2.5)

func async(group: DispatchGroup, execute: DispatchWorkItem)
//Schedules a work item asynchronously for execution and associates it with the specified dispatch group.

func async(group: DispatchGroup?, qos: DispatchQoS, flags: DispatchWorkItemFlags, execute: () -> Void)
//Schedules a block asynchronously for execution and optionally associates it with a dispatch group.

1.6 Managing Queue Attributes 管理队列属性

var label: String
/he label you assigned to the dispatch queue at creation time.

var qos: DispatchQoS
//The quality-of-service level assgined to the queue.

func setTarget(queue: DispatchQueue?)
//Specifies the dispatch queue on which to perform work associated with the current object.

func setTarget(queue: DispatchQueue?)需要避免循环设置;queue = Nil时, the system will provide a queue that is appropriate for the current object.

⭑⭑⭑⭑ Important

When setting up target queues, it is a programmer error to create cycles in the dispatch queue hierarchy. In other words, don't set the target of queue A to queue B and set the target of queue B to queue A.

1.7 Getting and Setting Contextual Data (待完善)

1.8 Managing the Main Dispatch Queue

func dispatchMain() -> Never
//Executes blocks submitted to the main queue.
/*
This function "parks" the main thread and waits for blocks to be submitted to the main queue.
Applications that call UIApplicationMain(_:_:_:_:) (iOS), NSApplicationMain(_:_:) (macOS), 
or CFRunLoopRun() on the main thread must not call dispatchMain().
*/

1.9 Scheduling Combine Publishers (待完善)


2.DispatchGroup

class DispatchGroup: DispatchObject

ref: https://developer.apple.com/documentation/dispatch/dispatchgroup

DispatchGroup允许您聚合一组任务并同步组上的行为。 可以将多个工作项附加到组,并安排它们在同一队列或不同队列上进行异步执行。 当所有工作项完成执行时,该组将执行其完成处理程序。 您还可以同步等待组中的所有任务完成执行。

2.1 初始化 init

2.2 Completion Handler

func notify(qos: DispatchQoS, flags: DispatchWorkItemFlags, queue: DispatchQueue, execute: () -> Void)

//Schedules the submission of a block with the specified attributes to a queue when all tasks in the current group have finished executing.

func notify(queue: DispatchQueue, work: DispatchWorkItem)
//Schedules the submission of a block to a queue when all tasks in the current group have finished executing.

2.3 Waiting for Tasks to Finish Executing

func wait()
//Waits synchronously for the previously submitted work to finish.

func wait(timeout: DispatchTime) -> DispatchTimeoutResult
//Waits synchronously for the previously submitted work to complete, and returns if the work is not completed before the specified timeout period has elapsed.

func wait(wallTimeout: DispatchWallTime) -> DispatchTimeoutResult
//Waits synchronously for the previously submitted work to complete, and returns if the work is not completed before the specified timeout period has elapsed.

2.4 显示地往Group中添加任务, 修改group中任务计数

* Updating the Group Manually 手动更新group
func enter()
//Explicitly indicates that a block has entered the group.
//
func leave()
//Explicitly indicates that a block in the group finished executing.

2.5 隐式往Group中添加任务

* Dispatching Work to Groups
DispatchQueue 's methods
func async(group: DispatchGroup, execute: DispatchWorkItem)
//Schedules a work item asynchronously for execution and associates it with the specified dispatch group.

func async(group: DispatchGroup?, qos: DispatchQoS, flags: DispatchWorkItemFlags, execute: () -> Void)
//Schedules a block asynchronously for execution and optionally associates it with a dispatch group.

3.DispatchWorkItem

The work you want to perform, encapsulated in a way that lets you attach a completion handle or execution dependencies.

A DispatchWorkItem encapsulates work to be performed on a dispatch queue or within a dispatch group. You can also use a work item as a DispatchSource event, registration, or cancellation handler.

class DispatchWorkItem

3.1 Creating a Work Item 初始化

init(qos: DispatchQoS, flags: DispatchWorkItemFlags, block: () -> Void)
//Creates a new dispatch work item from an existing block and assigns it the specified quality-of-service class.

struct DispatchWorkItemFlags
//A set of behaviors for a work item, such as its quality-of-service class and whether to create a barrier or spawn a new detached thread.

static let assignCurrentContext: DispatchWorkItemFlags
static let barrier: DispatchWorkItemFlags //标记为栅栏任务, 等待前面的异步任务都完成, 再执行栅栏任务
static let detached: DispatchWorkItemFlags
static let enforceQoS: DispatchWorkItemFlags
static let inheritQoS: DispatchWorkItemFlags
static let noQoS: DispatchWorkItemFlags

3.2 Executing the Work Item 执行一个workitem

func perform()
//Executes the work item's block synchronously on the current thread.

3.3 Adding a Completion Handle 添加一个完成回调

func notify(queue: DispatchQueue, execute: DispatchWorkItem)
//Schedules the execution of the specified work item after the completion of the current work item.

func notify(qos: DispatchQoS, flags: DispatchWorkItemFlags, queue: DispatchQueue, execute: () -> Void)
//Schedules the execution of the specified work item, with the specified quality-of-service, after the completion of the current work item.


3.4 Waiting for the Completion of a Work Item 等待任务完成

func wait()
//Causes the caller to wait synchronously until the dispatch work item finishes executing.

func wait(timeout: DispatchTime) -> DispatchTimeoutResult
//Causes the caller to wait synchronously until the dispatch work item finishes executing, or until the specified time elapses.

func wait(wallTimeout: DispatchWallTime) -> DispatchTimeoutResult
//Causes the caller to wait synchronously until the dispatch work item finishes executing, or until the specified time elapses.

struct DispatchTime
//A point in time relative to the default clock, with nanosecond precision.

struct DispatchWallTime
//An absolute point in time according to the wall clock, with microsecond precision.

3.5 Canceling a Work Item 取消执行m

func cancel()
//Cancels the current work item asynchronously.

var isCancelled: Bool
//A Boolean value indicating whether the work item has been canceled.

DEMO

1.栅栏线程实现

//定义
lazy var queue: DispatchQueue = {
    //自定义一个串行队列
    //let d = DispatchQueue.init(label: "serial")
    //自定义一个并发队列, 附加到全局队列中
    let d = DispatchQueue(label: "concurrent", qos: DispatchQoS.default, attributes: DispatchQueue.Attributes.concurrent, target: DispatchQueue.global())
    return d
}()
private var group = DispatchGroup()

//按钮点击事件
func clickBtn(_ sender: UIButton) {
  queue.async(group: group) {
            Thread.sleep(forTimeInterval: 5)
            print("\(Date())~~  \(Thread.current)--- \(Thread.current.isMainThread) ~~~ [ sleep \(4) ]")
        }
        queue.async(group: group) {
            Thread.sleep(forTimeInterval: 4)
            print("\(Date())~~  \(Thread.current)--- \(Thread.current.isMainThread) ~~~ [ sleep \(3) ]")
        }
        self.queue.async(group: self.group, qos: DispatchQoS.default, flags: DispatchWorkItemFlags.barrier, execute: {
            print("\(Date())~~  \(Thread.current)--- \(Thread.current.isMainThread) ~~~ [ sleep \(0) ]")
        })
        queue.async(group: group) {
            Thread.sleep(forTimeInterval: 2)
            print("\(Date())~~  \(Thread.current)--- \(Thread.current.isMainThread) ~~~ [ sleep \(2) ]")
        }
        group.notify(queue: DispatchQueue.main) {
            print("\(Date()) 所有任务完成  \(Thread.current)--- \(Thread.current.isMainThread) ~~~ [ \(999) ]")
        }
 }
 //打印结构
 /*
2019-06-18 07:21:54 +0000~~  <NSThread: 0x600000ee40c0>{number = 5, name = (null)}--- false ~~~ [ sleep 3 ]
2019-06-18 07:21:55 +0000~~  <NSThread: 0x600000ee4540>{number = 6, name = (null)}--- false ~~~ [ sleep 4 ]
2019-06-18 07:21:55 +0000~~  <NSThread: 0x600000ee4540>{number = 6, name = (null)}--- false ~~~ [ sleep0 ]
2019-06-18 07:21:57 +0000~~  <NSThread: 0x600000ee4540>{number = 6, name = (null)}--- false ~~~ [ sleep 3 ]
2019-06-18 07:21:57 +0000 所有任务完成  <NSThread: 0x600000e92980>{number = 1, name = main}--- true ~~~ [ 999 ]
 */
上一篇下一篇

猜你喜欢

热点阅读