Search code examples
swiftstructsingletonswift5

Why not use a struct-based singleton in Swift


Why not use a struct-based singleton?

I created decodable struct-based singleton.

struct Person: Decodable {
    static var shared = Person()

    private(set) var name: String?
                 var age: Int?
   
    private init() {
    
    }

    mutating func initData(from data: Data) {
        if let person = try? JSONDecoder().decode(Person.self, from: data) {
            self = person
        }
    }
}

init from other class like this:

Person.shared.initData(from: data)

and use parameters:

let name = Person.shared.name 
Person.shared.name = "MyName" //error


Person.shared.age  = 20

Is this the wrong way?


Solution

  • You can't use a struct fora singleton because struct is a value type so when you assign it to a variable you get a copy. This can be easily shown

    struct Singleton {
        static var shared = Singleton()
        var value: Int
    
        private init() {
            value = 0
        }
    }
    
    Singleton.shared.value = 1
    var otherSingleton = Singleton.shared
    otherSingleton.value = 2
    

    Now if we print the value of both

    print(Singleton.shared.value, otherSingleton.value)
    

    we get

    1 2

    So otherSingleton is clearly a separate instance so now we have 2 singletons :)

    But if we simply change the type of Singleton to class that is a reference type and then run the same code the result of the print is

    2 2

    since it is the same instance we have changed the value property for.