Chary 是一个 DispatchQueue 实用工具,用于更安全地进行同步和异步编程。它可以帮助您在处理多线程应用程序时避免竞争条件。
Chary 可通过 CocoaPods 获得。要安装它,只需将以下行添加到您的 Podfile 中
pod 'Chary'
在 Package.swift 中添加为您的目标依赖项
dependencies: [
.package(url: "https://github.com/hainayanda/Chary.git", .upToNextMajor(from: "1.0.7"))
]
在您的目标中使用它作为 Chary
.target(
name: "MyModule",
dependencies: ["Chary"]
)
Nayanda Haberty, hainayanda@outlook.com
Pharos 在 MIT 许可下可用。有关更多信息,请参见 LICENSE 文件。
Chary 提供了两个实用工具,Atomic
属性包装器和 DispatchQueue
扩展
Atomic 属性包装器是一个属性包装器,用于包装一个属性,以便可以原子地访问和编辑它
class MyClass {
@Atomic var atomicString: String = "atomicString"
...
...
}
那么,无论在哪里访问或编辑 atomicString,它都是线程安全的。
DispatchQueue.main.async {
myClass.atomicString = "from main thread"
}
DispatchQueue.global().async {
myClass.atomicString = "from global thread"
}
Chary 具有一些 DispatchQueue 扩展,这些扩展将在处理多线程时有所帮助。
您可以使用 isCurrentQueue(is:)
检查当前的 DispatchQueue,该方法将检查给定的队列是否为当前队列。
myQueue = DispatchQueue(label: "myQueue")
myQueue.sync {
// this will print true
print(DispatchQueue.isCurrentQueue(is: myQueue))
}
// this will print false
print(DispatchQueue.isCurrentQueue(is: myQueue))
它所做的是注册给定的 DispatchQueue 以进行检测,并将当前可检测的队列与给定的队列进行比较。
public static func isCurrentQueue(is queue: DispatchQueue) -> Bool {
queue.registerDetection()
return current == queue
}
调用 DispatchQueue.current
并不能保证返回当前的 DispatchQueue
,因为它只能返回已经注册用于检测的 DispatchQueue
。 当调用 current
时,有一些默认的 DispatchQueue
会自动注册。
DispatchQueue.main
DispatchQueue.global()
DispatchQueue.global(qos: .background)
DispatchQueue.global(qos: .default)
DispatchQueue.global(qos: .unspecified)
DispatchQueue.global(qos: .userInitiated)
DispatchQueue.global(qos: .userInteractive)
DispatchQueue.global(qos: .utility)
除此之外,它需要手动调用 registerDetection()
以允许通过调用 DispatchQueue.current
来访问 DispatchQueue
。 由于 isCurrentQueue(is:)
将自动注册给定的 DispatchQueue
,因此传递的队列将在之后可以通过 DispatchQueue.current
访问。
如果在同一个 DispatchQueue
中调用,从 DispatchQueue
运行 sync
有时会引发异常。 为了避免这种情况,您可以使用 safeSync
代替,它将首先检查当前队列,并决定是需要立即运行该块,还是使用默认的 sync
。 您无需注册 DispatchQueue
,因为它会在检查之前自动注册 DispatchQueue
DispatchQueue.main.safeSync {
print("this will safely executed")
}
有时,如果您在正确的 DispatchQueue
中,则希望立即执行操作,而不是使用 async
异步运行它。 例如,当您更新 UI 时,如果您已经在 DispatchQueue.main 中,最好立即运行它,而不是将其放入异步队列中。 您可以使用 asyncIfNeeded
立即实现该功能。 它将检查当前的 DispatchQueue
,并决定是需要立即运行还是使用默认的 async
。 您无需注册 DispatchQueue
,因为它会在检查之前自动注册 DispatchQueue
DispatchQueue.main.asyncIfNeeded {
print("this will executed right away or asynchronously if in different queue")
}
你知道怎么做。 只需克隆并进行 pull request