Swift - 简单的线程封装
2020-12-04 本文已影响0人
小猪蛋蛋
一、多线程开发-异步
创建一个新的swift文件,然后写上下面的代码
public typealias Task = () -> Void
public struct Asyncs{
//子线程操作
public static func async(_ task: @escaping Task) {
_async(task)
}
//子线程操作完成后主线程操作
public 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)
}
}
}
调用的时候:
//子线程操作的事情
Asyncs.async {
print(3,Thread.current)
}
//子线程操作完成后回到主线程操作
Asyncs.async {
print(1,Thread.current)
} mainTask: {
print(2,Thread.current)
}
// 3 <NSThread: 0x600002f48080>{number = 7, name = (null)}
// 1 <NSThread: 0x600002f5f780>{number = 6, name = (null)}
// 2 <NSThread: 0x600002f10900>{number = 1, name = main}
二、多线程开发-延时
public typealias Task = () -> Void
public struct Delay{
@discardableResult
public static func delay(_ seconds: Double, _ block: @escaping Task) -> DispatchWorkItem {
let item = DispatchWorkItem(block: block)
//main主线程延时操作
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + seconds, execute: item)
return item
}
}
三、多线程开发-异步延时
public struct AsyncDelay {
@discardableResult
public static func asyncDelay(_ seconds: Double,
_ task: @escaping Task) -> DispatchWorkItem {
return _asyncDelay(seconds, task)
}
@discardableResult
public static func asyncDelay(_ seconds: Double,
_ task: @escaping Task,
_ mainTask: @escaping Task) -> DispatchWorkItem { return _asyncDelay(seconds, task, mainTask)
}
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
}
}
四、多线程开发-once
dispatch_once在Swift中已被废弃,取而代之可以用类型属性或者全局变量\常量,默认自带 lazy + dispatch_once 效果。
例如:
fileprivate let initTask2: Void = {
print("initTask2---------")
}()
class ViewController: UIViewController {
static let initTask1: Void = {
print("initTask1---------")
}()
override func viewDidLoad() {
super.viewDidLoad()
let _ = Self.initTask1
let _ = initTask2
}
}
五、多线程开发-加锁
有时为了线程安全,我们需要为线程加锁,例如下面例子,当我们写一个缓存的时候,为防止多条线程同时访问同一个资源,我们为资源加锁。
public class Cache {
private static var data = [String: Any]()
//锁
private static var lock = DispatchSemaphore(value: 1)
static func set(_ key: String, _ value: Any) {
lock.wait()
defer { lock.signal() } //移除枷锁
data[key] = value
}
}