我有和应用程序有一个单一的存储整个应用程序的信息.但是,当使用来自不同线程的单例时,这会产生一些数据争用问题.
这里有一个非常虚拟和简单化的问题版本:
独生子
class Singleton {
static var shared = Singleton()
var foo: String = "foo"
}
Run Code Online (Sandbox Code Playgroud)
单例的使用(为简单起见,来自AppDelegate)
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
DispatchQueue.global().async {
var foo = Singleton.shared.foo // Causes data race
}
DispatchQueue.global().async {
Singleton.shared.foo = "bar" // Causes data race
}
return true
}
}
Run Code Online (Sandbox Code Playgroud)
有没有办法确保单例是线程安全的,所以它可以在应用程序的任何地方使用,而不必担心你在哪个线程?
这个问题不是在Swift中使用dispatch_once单例模型的重复,因为(如果我理解正确的话)那里他们正在解决访问单例对象本身的问题,但不能确保其属性的读写完成线程安全.
该框架包在其 Package.swift 文件中具有以下依赖项:
.package(url: "https://github.com/marmelroy/PhoneNumberKit.git", .upToNextMajor(from: "3.3.0")),
Run Code Online (Sandbox Code Playgroud)
Package.resolved 引用此 PhoneNumberKit 的部分如下所示:
{
"identity" : "phonenumberkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/marmelroy/PhoneNumberKit.git",
"state" : {
"revision" : "6edd6e38a30aec087cb97f7377edf876c29a427e",
"version" : "3.5.9"
}
}
Run Code Online (Sandbox Code Playgroud)
但是,当我打开 Xcode 时,它会自动执行“解析包图”步骤,将 Package.resolved 修改为:
{
"identity" : "phonenumberkit",
"kind" : "remoteSourceControl",
"location" : "https://github.com/marmelroy/PhoneNumberKit.git",
"state" : {
"revision" : "56f612ea0178406b1ff57846401bd68a57d96a80",
"version" : "3.5.4"
}
}
Run Code Online (Sandbox Code Playgroud)
对我来说,这根本没有意义,拥有 Package.resolved 文件的目的应该是确保从事同一项目的所有开发人员对所有依赖项使用相同的版本。
为什么Xcode会自动修改这个依赖的版本?
注意:我已将此 PhoneNumberKit 包放在这里作为示例,但实际上其他包也发生在我身上