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?
To clarify the bizarre results show database I/o errors because of two instances trying to access the db at once
Update
please see this question for more info on the database code: Using transactions to insert is throwing errors Sqlite.swift
You can create a thread safe singleton using DispatchQueue. We will create a serial queue and add a sync method to set and get value. Below is the code you can achieve thread safe singleton class. It will write an another blog where we can improve the performance using dispatch barrier.
Thread Safe Singleton in JavaCreate the private constructor to avoid any new object creation with new operator. Declare a private static instance of the same class. Provide a public static method that will return the singleton class instance variable.
Additionally, singletons should be protected against concurrent usage in order to avoid synchronisation issues, and thread safe singletons could lead to a performance bottleneck if they're being used by multiple threads in parallel, which can be avoided.
In short, this means that the Name class is not thread-safe. To fix the above race condition, we need to synchronize how threads get to access and modify the state of this class. If we make it so that Thread 2 cannot start running setFullName until Thread 1 finishes doing so, the scenario above would become impossible.
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
Swift 3.0
class ClassName {
static let sharedInstance: ClassName = { ClassName()} ()
}
USE: let object:ClassName = ClassName.shareInstance
In Swift 3.0 add a private init to prevent others from using the default () initializer.
class ClassName {
static let sharedInstance = ClassName()
private init() {} //This prevents others from using the default '()' initializer for this class.
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With