66

There are some posts for how to write code for static constant and static variable in Swift. But it is not clear when to use static constant and static variable rather than constant and variable. Can someone explain?

informatik01
  • 16,038
  • 10
  • 74
  • 104
Mike
  • 817
  • 1
  • 8
  • 15

4 Answers4

136

When you define a static var/let into a class (or struct), that information will be shared among all the instances (or values).

Sharing information

class Animal {
    static var nums = 0

    init() {
        Animal.nums += 1
    }
}

let dog = Animal()
Animal.nums // 1
let cat = Animal()
Animal.nums // 2

As you can see here, I created 2 separate instances of Animal but both do share the same static variable nums.

Singleton

Often a static constant is used to adopt the Singleton pattern. In this case we want no more than 1 instance of a class to be allocated. To do that we save the reference to the shared instance inside a constant and we do hide the initializer.

class Singleton {
    static let sharedInstance = Singleton()

    private init() { }

    func doSomething() { }
}

Now when we need the Singleton instance we write

Singleton.sharedInstance.doSomething()
Singleton.sharedInstance.doSomething()
Singleton.sharedInstance.doSomething()

This approach does allow us to use always the same instance, even in different points of the app.

Luca Angeletti
  • 58,465
  • 13
  • 121
  • 148
  • 2
    Thank you. This explains very clearly. Can you confirm if my understanding is correct: 1. As some documentation mentions, static variable and constant are type here, not instance; 2. It can be used in the way like property of the class. – Mike Jun 08 '16 at 12:04
  • 1
    @Mike: 1) A static var/let can reference an instance of a class (like in my `Singleton` example) or can store a value (like in the `Animal` example). Just like plain var/let. 2) Yes we can see a `static var/let` like a property that belong to the class itself and not to the instance. – Luca Angeletti Jun 08 '16 at 12:06
  • Thanks. Now I understand absolutely how to use static. – Mike Jun 08 '16 at 12:10
  • 1
    *1*.Static variables in a class are at class level, not object level(we dont need to initialize the class to access the variable). *2*. Static variable have same reference across different instances of class *3*. Static variables are not visible to subclasses. – Saif Apr 27 '17 at 07:44
  • Thanks very much. This was so confusing for me very long time. But now its clear. – Vincent Joy Dec 06 '17 at 06:13
  • Thank you very much. Besides static properties, I now also understand what a singleton is. – Sanjeevcn Aug 22 '19 at 07:26
23

There are some posts for how to write code for static constant and static variable in Swift. But it is not clear when to use static constant and static variable rather than constant and variable. Can someone explain? When you define a static var/let into a class (or struct), that value will be shared among all the instances (or values).

static variables/class are variables can be accessed without need of creation of any instance/object.

class Human {
    static let numberOfEyes = 2 //human have only 2 eyes
    static var eyeDefect = false //whether human have side-effect or not. he can have defect later so its variable

    //other variables and functions
}

//you can access numberOfEyes like below no object of Human is created
print(Human.numberOfEyes)
print(Human.eyeDefect)

//Object of Human
let john = Human()

I think you know difference between constant and variable. In short, constant is that whose value never changes; numberOfEyes in above example and variable is that whose value changes; eyeDefect in above example.

static constant or variables are placed in memory(RAM) separate then the Objects. i.e. numberOfEyes have different memory space allocated than John object, its not inside John.

now, when to use static constants/variables:

  1. When you use singleton design pattern: static let sharedInstance = APIManager()

    class APIManager(){
        static let sharedInstance = APIManager()
        //Your other variables/functions here below
    }
    //Use it as to get singleton instance of APIManager from anywhere in your application
    let instanceOfAPIManager = APIManager.sharedInstance
    
  2. When you need value of anything that is globally the same without need to make instance of the class under which it is defined like numberOfEyes in human class.

  3. Use of static variables/constants are not much recommended because of memory issues because once it's instantiated/assigned, it remains in memory until your application gets removed from the memory. I have found till now the best place to use static variables/constants is only while making singleton pattern and sometimes pointers for other normal variables and constants don't use static because: memory issue, it will be difficult to run unit testing in your code with static variables/constants. Not recommended to use as like in Human class also. instead use them as just constant or variables and access them by making instance.

    class Human {
     let numberOfEyes = 2 //human have only 2 eyes
     var eyeDefect = false //whether human have side-effect or not. he can have defect later so its variable
    
       //other variables and functions
     }
    
    //you can access numberOfEyes like below if you need just those values.
    print(Human().numberOfEyes)
    print(Human().eyeDefect)
    
Bibek
  • 3,689
  • 3
  • 19
  • 28
10

Static constants and variables do belong to the class itself, not to a particular instance. A class can also have static methods that can be called without creating an instance of a class.

So when you have a class MyClass with a static var x, you can also access it through MyClass.x directly. x will be shared among all instances of a class

Julia Will
  • 616
  • 3
  • 8
3

This is more of an important comment:

class Person {
    static var name = "Static John" // a property of Person 'type'
    var name = "Alex" // a property of Person 'instance'

    var nonStaticName = "Peter"
    static var staticName = "Sara"



    static func statFunc() {
        let x = Person.name // Static John
        let y = name // Static John or Alex?!  Static John!!!!
        let r = staticName // Sara
        let k = nonStaticName // ERROR: instance member 'nonStaticName' cannot be used on type 'Person'
        // The compiler is like: I'm referring to the `nonStaticName` property of which instance?! There is no instance! Sorry can't do!

    }

    func nonStaticFunc() {
        let x = Person.name // Static John
        let y = name // Static John or Alex?! Alex!!! Because we're in a instance scope...
        let k = nonStaticName // Obviously works
        let r = staticName // ERROR: static member 'staticName' cannot be used on instance of type 'Person'. Person.staticName will work
    }
}

Interesting observations:

First:

static var name = "Static John" // a property of Person 'type'
var name = "Alex" // a property of Person 'instance'

creates no conflicts.

Second:

You can't ever use instance variables inside static variables. You can use static variables inside instance functions if you refer to it by prefixing it with the type ie do Person.name, whereas

static variables can be accessed inside static functions with or without prefixing the type ie Person.staticName or staticName both work.

mfaani
  • 33,269
  • 19
  • 164
  • 293