From reading it seems like the best advice for creating a singleton in Swift is to use static let
like this:
struct GameManager {
static let defaultManager = GameManager()
var gameScore = 0
var saveState = 0
private init() {}
}
GameManager.defaultManager.gameScore = 1024 // Error
GameManager.defaultManager.saveState = 12 // Error
let score = GameManager.defaultManager.gameScore
let savedProgress = GameManager.defaultManager.saveState
Because the defaultManager
is declared as a constant (with "let"), there is an error when I try to assign gameScore
and saveState
.
I'm running Xcode 7.0 beta 6 (7A192o) with Swift 2.0 (swiftlang-700.0.57.3 clang-700.0.72).
If I change the defaultManager
to be declared as a variable (with "var"), will it no longer be considered a proper singleton?
If I change the GameManager to be declared as a class instead of a structure, then the code works as expected.
class GameManager {
static let defaultManager = GameManager()
var gameScore = 0
var saveState = 0
private init() {}
}
GameManager.defaultManager.gameScore = 1024 // No error, why?
GameManager.defaultManager.saveState = 12 // No error, why?
let score = GameManager.defaultManager.gameScore // 1,024
let savedProgress = GameManager.defaultManager.saveState // 12
Can you explain why the reference-type class is better for implementing the singleton than the value-type structure?
You can't really change it because on your struct you have a let
constant named defaultManager
. As you know already a struct is a copy type while a class is a pass by reference one. if you want to use it as a struct you will have to replace that let
with var
instead. Another take of this problem is to change the struct to a class
that way you will be able to change the defaultManager
value although it is declared as a let
.
cheers
edit: The main difference in your code is that when you have a constant in a class
and you change that constant you are actually referring to its address rather than its actual value.Same doesn't happen with a struct
cause as a value type you can't do that call by reference thingy you do with class
and so you are forced to have a constant(let
) value that cannot be mutated. Change the let
to var
inside your struct
and see the magic happen