如何使Swift Class Singleton实例线程安全?

时间:2021-08-10 16:01:00

I have a singleton class as so:

我有一个单例类如下:

class Database {
   static let instance:Database = Database()
   private var db: Connection?

   private init(){
      do {
        db = try Connection("\(path)/SalesPresenterDatabase.sqlite3")
        }catch{print(error)}
   }
}

Now I access this class using Database.instance.xxxxxx to perform a function within the class. However when I access the instance from another thread it throws bizarre results as if its trying to create another instance. Should I be referencing the instance in the same thread?

现在我使用Database.instance.xxxxxx访问此类以在类中执行函数。但是,当我从另一个线程访问该实例时,它会抛出奇怪的结果,就像它试图创建另一个实例一样。我应该在同一个线程中引用该实例吗?

To clarify the bizarre results show database I/o errors because of two instances trying to access the db at once

澄清奇怪的结果显示数据库I / O错误,因为两个实例一次尝试访问数据库

Update
please see this question for more info on the database code: Using transactions to insert is throwing errors Sqlite.swift

更新请参阅此问题以获取有关数据库代码的更多信息:使用事务插入是抛出错误Sqlite.swift

2 个解决方案

#1


5  

class var shareInstance: ClassName {

    get {
        struct Static {
            static var instance: ClassName? = nil
            static var token: dispatch_once_t = 0
        }
        dispatch_once(&Static.token, {
            Static.instance = ClassName()
        })
        return Static.instance!
    }
}

USE: let object:ClassName = ClassName.shareInstance

USE:let object:ClassName = ClassName.shareInstance

Swift 3.0

Swift 3.0

class ClassName {
  static let sharedInstance: ClassName = { ClassName()} ()
}

USE: let object:ClassName = ClassName.shareInstance

USE:let object:ClassName = ClassName.shareInstance

#2


3  

In Swift 3.0 add a private init to prevent others from using the default () initializer.

在Swift 3.0中添加一个私有init以防止其他人使用default()初始化程序。

class ClassName {
  static let sharedInstance = ClassName()
  private init() {} //This prevents others from using the default '()' initializer for this class.
}

#1


5  

class var shareInstance: ClassName {

    get {
        struct Static {
            static var instance: ClassName? = nil
            static var token: dispatch_once_t = 0
        }
        dispatch_once(&Static.token, {
            Static.instance = ClassName()
        })
        return Static.instance!
    }
}

USE: let object:ClassName = ClassName.shareInstance

USE:let object:ClassName = ClassName.shareInstance

Swift 3.0

Swift 3.0

class ClassName {
  static let sharedInstance: ClassName = { ClassName()} ()
}

USE: let object:ClassName = ClassName.shareInstance

USE:let object:ClassName = ClassName.shareInstance

#2


3  

In Swift 3.0 add a private init to prevent others from using the default () initializer.

在Swift 3.0中添加一个私有init以防止其他人使用default()初始化程序。

class ClassName {
  static let sharedInstance = ClassName()
  private init() {} //This prevents others from using the default '()' initializer for this class.
}