How to reset singleton instance?
All you want is possible, but highly unrecommended :) Because singletons by design should not fall back to nil.
First, if you want to change currentUser
, it must be var
. Then if you want it to be nil, it must by optional type and you should unwrap it when using.
static var currentUser: User? = User()
I would propose to not change currentUser
or make it non-static (for example, a property of some UsersManager
.
Also you can change properties of currentUser
(like name
, loggedIn
). At last, take a look at this answer: https://stackoverflow.com/a/28398974/326017 - it describes your situation.
You can not do that if you declare currentUser
as let
. It should be var
instead, or better still private (set) var
. Also you can not assign currentUser
with nil
if its type is User
(inferred from the way you assign it at the moment). Instead, it should be User?
.
For example, something like this:
/// ...
static private (set) var currentUser: User? = User()
static func resetCurrentUser() {
currentUser = nil
}
// ...
private (set)
allows changes to the property only within the scope of current file, and for the rest of your code it will be seen as let
. Then method resetCurrentUser()
can be used to put it to nil
.
Or even this:
// ...
private static var _currentUser: User?
static var currentUser: User {
if _currentUser == nil { _currentUser = User() }
return _currentUser!
}
static func resetCurrentUser() {
_currentUser = nil
}
// ...
You can have currentUser
as computed property that guarantees to return a value. So you can reset the user to nil
, yes. But if later you will try to read from there again a new instance will be created automatically.
Be careful with multithreaded access, though.
I create all my Singletons with an optional
Singleton instance.
However I also make this private
and use a function to fetch it.
If the Singleton is nil
it creates a new instance.
This is actually the only good way to set up a Singleton. If you have a regular object that you can't deinitialize it's a memory problem. Singletons are no different, except that you have to write a function to do it.
Singletons have to be completely self managed. This means from init to deinit.
I have a couple of templates on github for Singeltons, one of them with a fully implemented read/write lock.
class Singleton {
private static var privateShared : Singleton?
class func shared() -> Singleton { // change class to final to prevent override
guard let uwShared = privateShared else {
privateShared = Singleton()
return privateShared!
}
return uwShared
}
class func destroy() {
privateShared = nil
}
private init() {
print("init singleton")
}
deinit {
print("deinit singleton")
}
}