Myron Work Space 的每周一记iOS Developer程序员

GCD

2016-08-06  本文已影响69人  黄穆斌

这是一篇我关于 GCD 的使用以及学习的总结文章。持续更新。
感谢诸多大神在此之前写的各类文章,如果可以,我会尽量把他们添加到附录中,如有遗漏,感谢提醒补充和讨论。
2016-08-06


成果

假如你对我的废话没兴趣,那么看到这里就够了。这是我存在 GitHub 上的代码文件,假如链接失效,你可以给我留言。
GCD.swift

为何 GCD

我在工作中经常使用 GCD,因为我感觉这样的代码更加直接了当,如果不是必要情况,我甚至不愿意使用 NSThread,NSOperationQueue,当然,有时候,这是一种非常折腾的癖好。
总之,这些都是多线程管理工具,如果你有兴趣,简书上有非常简单易懂的资料。稍微搜索一下即可。
至于好处,我只说一点。
这是 iOS 提供的最底层的多线程接口。

基础概念

--> 名词解释

--> GCD 变量

---> dispatch_queue_t:队列

    func TestGCD() {
        var queue: dispatch_queue_t
        // 创建串行队列
        queue = dispatch_queue_create("A Serial Queue", DISPATCH_QUEUE_SERIAL)
        // 创建并行队列
        queue = dispatch_queue_create("A Concurrent", DISPATCH_QUEUE_CONCURRENT)
        // 获取程序主队列
        queue = dispatch_get_main_queue()
        // 获取程序全局队列
        queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
    }

---> dispatch_source_t: GCD 基础数据类型

官方解释:GCD provides a suite of dispatch sources—interfaces for monitoring (low-level system objects such as Unix descriptors, Mach ports, Unix signals, VFS nodes, and so forth) for activity. and submitting event handlers to dispatch queues when such activity occurs. When an event occurs, the dispatch source submits your task code asynchronously to the specified dispatch queue for processing.
翻译:GCD 提供一个系列的调度源接口用来监听活动(底层的系统对象:例如 Unix 描述符,Mach 端口,Unix 信号,VFS 节点等等)。并且在活动发生的时候发送事件句柄给调度的队列。当一个事件发生的时候,发送源派遣你的任务代码到指定的派遣队列中异步执行。

--> GCD 方法

---> 基础方法

----> dispatch_sync(queue: dispatch_queue_t, block: dispatch_block_t)

    func TestGCD() {
        // dispatch_sync(queue: dispatch_queue_t, block: dispatch_block_t)
        // 同步执行方法,会堵塞当前的线程,然后把该任务完成后才继续当前线程。
        // 注意:如果在 main_queue 中 dispatch_sync(queue: main_queue, block: {}) 会导致死锁
        
        print("Test Start in \(NSThread.currentThread()).")
        for i in 0 ..< 10 {
            dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
                print("Test \(i) Run in \(NSThread.currentThread()).")
            }
        }
        print("Test End in \(NSThread.currentThread()).")
    }

/* 运行结果
Test Start in <NSThread: 0x7fa490504cb0>{number = 1, name = main}.
Test 0 Run in <NSThread: 0x7fa490504cb0>{number = 1, name = main}.
Test 1 Run in <NSThread: 0x7fa490504cb0>{number = 1, name = main}.
Test 2 Run in <NSThread: 0x7fa490504cb0>{number = 1, name = main}.
Test 3 Run in <NSThread: 0x7fa490504cb0>{number = 1, name = main}.
Test 4 Run in <NSThread: 0x7fa490504cb0>{number = 1, name = main}.
Test 5 Run in <NSThread: 0x7fa490504cb0>{number = 1, name = main}.
Test 6 Run in <NSThread: 0x7fa490504cb0>{number = 1, name = main}.
Test 7 Run in <NSThread: 0x7fa490504cb0>{number = 1, name = main}.
Test 8 Run in <NSThread: 0x7fa490504cb0>{number = 1, name = main}.
Test 9 Run in <NSThread: 0x7fa490504cb0>{number = 1, name = main}.
Test End in <NSThread: 0x7fa490504cb0>{number = 1, name = main}.
*/

----> dispatch_async(queue: dispatch_queue_t, block: dispatch_block_t)

    func TestGCD() {
        // dispatch_async(queue: dispatch_queue_t, block: dispatch_block_t)
        // 异步执行方法,不会堵塞当前的线程,但是运行顺序将不可控。
        
        print("Test Start in \(NSThread.currentThread()).")
        for i in 0 ..< 10 {
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
                print("Test \(i) Run in \(NSThread.currentThread()).")
            }
        }
        print("Test End in \(NSThread.currentThread()).")
    }
/* 运行结果
Test Start in <NSThread: 0x7fbe33c09bf0>{number = 1, name = main}.
Test End in <NSThread: 0x7fbe33c09bf0>{number = 1, name = main}.
Test 2 Run in <NSThread: 0x7fbe33e0b360>{number = 2, name = (null)}.
Test 0 Run in <NSThread: 0x7fbe33f018d0>{number = 3, name = (null)}.
Test 8 Run in <NSThread: 0x7fbe33e0b360>{number = 2, name = (null)}.
Test 1 Run in <NSThread: 0x7fbe33e0cf90>{number = 4, name = (null)}.
Test 3 Run in <NSThread: 0x7fbe33f05c90>{number = 5, name = (null)}.
Test 4 Run in <NSThread: 0x7fbe33f05880>{number = 6, name = (null)}.
Test 5 Run in <NSThread: 0x7fbe33d1dc60>{number = 7, name = (null)}.
Test 6 Run in <NSThread: 0x7fbe33d09660>{number = 8, name = (null)}.
Test 7 Run in <NSThread: 0x7fbe33f04cf0>{number = 9, name = (null)}.
Test 9 Run in <NSThread: 0x7fbe33f018d0>{number = 3, name = (null)}.
*/

---> dispatch_source_t 方法

----> dispatch_source_t dispatch_source_create( dispatch_source_type_t type, uintptr_t handle, unsigned long mask, dispatch_queue_t queue)

Creates a new dispatch source to monitor low-level system objects and automatically submit a handler block to a dispatch queue in response to events.
创建一个新的调度源来监听底层系统对象并在响应事件的时候自动提交处理块给派遣队列。

// 在主队列中创建一个定时器
var timer: dispatch_source_t = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue())
    // 创建 计时器 dispatch_source_t
    var source: dispatch_source_t? = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue())
    // 计数
    var sourceTimes = 10
    //
    func TestGCD() {
        // 设置 dispatch_source_t 为从现在开始每秒调用一次
        dispatch_source_set_timer(source!, dispatch_walltime(nil, 0), NSEC_PER_SEC, 0)
        // 设置调用时的处理
        dispatch_source_set_event_handler(source!) {
            // 打印当前线程,以及计数值,然后减1.
            print("\(self.sourceTimes): \(NSThread.currentThread())")
            self.sourceTimes -= 1
            // 如果计数结束则 释放 或 cancel, 都会导致停止,但是释放不会调用 cancel handler
            if self.sourceTimes <= 0 {
                //self.source = nil
                dispatch_source_cancel(self.source!)
            }
        }
        // 调用 cancel 的时候的处理
        dispatch_source_set_cancel_handler(source!) { 
            print("source Cancel: \(NSThread.currentThread())")
            self.source = nil
        }
        // 启动 source 监听
        dispatch_resume(source!)
    }

----> void dispatch_source_set_timer( dispatch_source_t source, dispatch_time_t start, uint64_t interval, uint64_t leeway) 设置计时器时间

Sets a start time, interval, and leeway value for a timer source.
设置计时器源的起始时间、 间隔和回旋余地值。

----> dispatch_time_t dispatch_walltime( const struct timespec *when, int64_t delta)

Creates a dispatch_time_t using an absolute time according to the wall clock.
根据挂钟来创建一个绝对事件。

----> dispatch_time_t dispatch_time( dispatch_time_t when, int64_t delta);

Parameters

Creates a dispatch_time_t relative to the default clock or modifies an existing dispatch_time_t.
根据默认的时钟创建一个 dispatch_time_t 或修改一个现有的 dispatch_time_t


参考文献

我的 GitHub 空间:Myron Work Space

上一篇下一篇

猜你喜欢

热点阅读