Swift-多线程

作者: 我为双鱼狂 | 来源:发表于2021-07-15 20:37 被阅读0次

    摘要

    本文不探讨子线程、主线程、同步和异步的常规操作。只是使用DispatchWorkItem 属性来处理1.子线程切换到主线程和2.主动停止正在进行的线程这两种场景,提供一些不同的实现思路。

    DispatchWorkItem还可以有其他的场景的应用,这次仅仅做个抛砖引玉。

    应用场景

    多线程主要的应用场景是:

    1. 子线程加载耗时操作,比如网络请求
    2. 延时操作
    3. 加锁处理

    API 及语言

    DispatchObject

    Swift

    核心逻辑/代码

    swift 中的多线程处理主要用DispatchQueue的函数。可以创建或者切换到其他线程;也可以设置async(异步)和sync(同步)状态。

    这里不再介绍常规操作,主要介绍使用DispatchWorkItem封装多线程函数,并可以自定义处理事件,比如停止多线程任务等。

    DispatchWorkItem: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.(DispatchWorkItem封装了要在调度队列或调度组中执行的工作。您还可以将工作项用作DispatchSource事件、注册或取消处理程序)

    封装中的主要功能:

    • 子线程处理完成后切换到主线程
    // 创建 workItem
    let item = DispatchWorkItem(block: task)
    // 子线程异步处理 workItem
    DispatchQueue.global().async(execute: item)
    // item 调用 notify 通知到主线程处理事件
    item.notify(queue: DispatchQueue.main, execute: main)
    
    • 异步延时处理,在延时的过程中,可以主动触发中断延时之后的处理
    // 封装延时操作方法
    @discardableResult
    private static func _asyncDelay(_ seconds: Double,
                                    _ task: @escaping Task,
                                    _ mainTask: Task? = nil) -> DispatchWorkItem {
        let item = DispatchWorkItem(block: task)
        DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + seconds, execute: item)
        if let main = mainTask {
            item.notify(queue: DispatchQueue.main, execute: main)
        }
        return item
    }
    // 实现 item 方法
    let item = Async.asyncDelay(2) {
        print("2 秒后处理事件")
    }
    
    // 主动关闭
    item.cancel()
    

    多线程 - once

    dispatch_once 在 Swift 中已被废弃,可以用类型属性或者全局变量/常量来达到lazy + dispatch_once 效果

    fileprivate let initTask2: Void = { print("initTask2")}()
    class Data {
        static let initTask1: Void = {
            print("initTask1")
        }()
        
        init() {
            // 该方法只会被实现一次
            let _ = Self.initTask1
            let _ = initTask2
        }
    }
    

    示例代码

    // MARK: - 多线程自定义封装
    struct Async {
        typealias Task = () -> Void
        
        // MARK: - 异步处理事件
        static func async(_ task: @escaping Task) {
            _async(task)
        }
        
        static func async(_ task: @escaping Task,
                          _ mainTask: @escaping Task) {
            _async(task, mainTask)
        }
        
        private static func _async(_ task: @escaping Task,
                                   _ mainTask: Task? = nil) {
            let item = DispatchWorkItem(block: task)
            DispatchQueue.global().async(execute: item)
            if let main = mainTask {
                item.notify(queue: DispatchQueue.main, execute: main)
            }
        }
        
        // MARK: - 延时处理事件
        @discardableResult
        static func asyncDelay(_ seconds: Double,
                               _ task: @escaping Task) -> DispatchWorkItem {
            return _asyncDelay(seconds, task)
        }
        
        @discardableResult
        static func asyncDelay(_ seconds: Double,
                               _ task: @escaping Task,
                               _ mainTask: @escaping Task) -> DispatchWorkItem {
            return _asyncDelay(seconds, task, mainTask)
        }
        
        @discardableResult
        private static func _asyncDelay(_ seconds: Double,
                                        _ task: @escaping Task,
                                        _ mainTask: Task? = nil) -> DispatchWorkItem {
            let item = DispatchWorkItem(block: task)
            DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + seconds, execute: item)
            if let main = mainTask {
                item.notify(queue: DispatchQueue.main, execute: main)
            }
            return item
        }
    }
    

    相关文章

      网友评论

        本文标题:Swift-多线程

        本文链接:https://www.haomeiwen.com/subject/qzpmpltx.html