Joakim Sjöstedt
Joakim Sjöstedt

Reputation: 948

Why can I create an instance of a static variable?

I have a class that looks like this:

class A {
    var aString = ""
    static var staticString = ""
}

If I create an instance of A I can't access the static property:

var a = A()
a.staticString = "THIS GIVES AN ERROR"

However, if I create a direct instance to the static variable it works:

var a = A.staticString
a = "THIS WORKS"

The way I understand static variables is that you should only be able to access them directly like this: A.staticString = "hello". But this doesn't seem to be the case.

What's more confusing (to me) is that I can create multiple instances with their own seperate values; that is the value doesn't remain static:

var a = A.staticString
a = "AAA"

var b = A.staticString
b = "BBB"
print(a) //prints AAA
print(b) //prints BBB

Isn't the whole point that a static variable should... remain static? In my head, both a and b should print BBB since b = "BBB" should have overwritten the first value assigned to it.

To make it even more confusing (to me), using a singleton does give me the result I expect:

class A {
    static let shared = A()
    var aString = ""
    static var staticString = ""
}
let instance1 = A.shared
instance1.aString = "A String"
        
let instance2 = A.shared
instance2.aString = "Another String"
        
print(instance1.aString, instance2.aString) //Both print "Another String"

Could some kind soul try to clear things up for me?

Upvotes: 0

Views: 296

Answers (1)

David Pasztor
David Pasztor

Reputation: 54745

The static keyword in Swift does not mean the property is immutable/constant (unlike in C-based languages). static means the property is a type property, not an instance property, meaning that it is a property of the type itself, shared between all instances and not a property of each instance. For more information, read the Type Properties section of the Swift language guide.

Constants/immutable properties are declared by let, while mutable ones by var.

You can set and get static vars by using the type name (A in your case).

A.staticString = "new"
A.staticString // "new"

If you create instances of the type, you can use type(of:) to get the meta-type (A), which you can use to access static properties

let a = A()
type(of: a).staticString // "new"
let anotherA = A()
type(of: anotherA).staticString  // "new"

Upvotes: 1

Related Questions