Static vs class functions/variables in Swift classes?
Asked Answered
J

8

483

The following code compiles in Swift 1.2:

class myClass {
    static func myMethod1() {
    }
    class func myMethod2() {
    }
    static var myVar1 = ""
}

func doSomething() {
    myClass.myMethod1()
    myClass.myMethod2()
    myClass.myVar1 = "abc"
}

What is the difference between a static function and a class function? Which one should I use, and when?

If I try to define another variable class var myVar2 = "", it says:

Class stored properties not yet supported in classes; did you mean 'static'?

When this feature is supported, what will the difference be between a static variable and a class variable (i.e. when both are defined in a class)? Which one should I use, and when?

(Xcode 6.3)

Janinejanis answered 14/4, 2015 at 20:17 Comment(2)
Similar question here: static vs class as class variable/method (Swift).Graber
Static Can be applied on Stored Property as well as Computed Properties. Class can only be applied on computed properties. iosarchitect.com/static-and-class-keyword-in-swiftMyotonia
D
804

static and class both associate a method with a class, rather than an instance of a class. The difference is that subclasses can override class methods; they cannot override static methods.

class properties function in the same way (subclasses can override them).

Deadly answered 14/4, 2015 at 20:23 Comment(18)
So what is the difference between final class function and 'static' function within a class?Bubbly
@hippo_san, in a base class the two are functionally the same. However, final can be used to cut off further overrides when used in a subclass. The two both have their place, I would say the use of static or final when used on a class function is trivial and up to your style choice.Prairial
ah, so static func foo(){} in Swift is like public static final foo(){} in Java?Turpentine
@Supuhstar: Basically, yes.Deadly
If the two are the same, then actually we don't need "static"?Jacalynjacamar
@allenlinli: They're not the same thing.Deadly
@Deadly I understand now. For class functions, we can replace "static" with "final class", but for properties in a class, we can have only static properties instead of class properties. So the "static" keyword still has its place.Jacalynjacamar
@Bubbly not the same. Number of Inheritance branches can be infinite. And maybe in some branch you prefer to close override and in some - not.Delorasdelorenzo
@mipadi, more precisely, Swift (for now it is Swift3) does not support class stored properties, but one can define class computed properties in Swift.Wormy
Note that class properties are allowed, but only within classesFlaggy
"final func" is just a "normal" one but prevented to be overridden nor redeclared by subclasses.Brown
Hmmm. Curious why "subclasses can override class methods; they cannot override static methods," but in 4.2 you can use static methods in a protocol, but you can not use class methods. Seems to me everything in a protocol is overridden, so shouldn't it be the other way around?Abmho
Also I think we can achieve the same as a static method using a final class, note, not a final class method. But this is probably overkillFreda
static functions can be overwritten as well, but you cannot call superFootsore
If the protocol allows us to define class methods then value types can not conform to those protocols. @Popmedic.Fortnight
Static functions can not be overridden in swift. @Peter Lapisu.Fortnight
What does even "not possible in Swift yet"? It was already included in language but could not be used? TBH, the more I code in Swift the clearer it gets that Swift is result of very shitty planning and designLegrand
@Farid: At the time, the feature was planned but had not yet been implemented (the answer was written in the Swift 1 days). Class properties have since been added.Deadly
K
86

I tried mipadi's answer and comments on playground. And thought of sharing it. Here you go. I think mipadi's answer should be mark as accepted.

class A{
    class func classFunction(){
    }
    static func staticFunction(){
    }
    class func classFunctionToBeMakeFinalInImmediateSubclass(){
    }
}

class B: A {
    override class func classFunction(){
        
    }
    
    //Compile Error. Class method overrides a 'final' class method
    override static func staticFunction(){
        
    }
    
    //Let's avoid the function called 'classFunctionToBeMakeFinalInImmediateSubclass' being overriden by subclasses
    
    /* First way of doing it
    override static func classFunctionToBeMakeFinalInImmediateSubclass(){
    }
    */
    
    // Second way of doing the same
    override final class func classFunctionToBeMakeFinalInImmediateSubclass(){
    }
    
    //To use static or final class is choice of style.
    //As mipadi suggests I would use. static at super class. and final class to cut off further overrides by a subclass
}

class C: B{
    //Compile Error. Class method overrides a 'final' class method
    override static func classFunctionToBeMakeFinalInImmediateSubclass(){
        
    }
}
Kimes answered 13/10, 2015 at 9:9 Comment(0)
F
32

Regarding to OOP, the answer is too simple:

The subclasses can override class methods, but cannot override static methods.

In addition to your post, if you want to declare a class variable (like you did class var myVar2 = ""), you should do it as follow:

class var myVar2: String {
    return "whatever you want"
}
Flyfish answered 26/6, 2015 at 23:14 Comment(0)
H
29

Testing in Swift 4 shows performance difference in simulator. I made a class with "class func" and struct with "static func" and ran them in test.

static func is:

  • 20% faster without compiler optimization
  • 38% faster when optimization -whole-module-optimization is enabled.

However, running the same code on iPhone 7 under iOS 10.3 shows exactly the same performance.

Here is sample project in Swift 4 for Xcode 9 if you like to test yourself https://github.com/protyagov/StructVsClassPerformance

Hokku answered 22/6, 2017 at 14:40 Comment(1)
was this on the simulator or physical device?Keeley
A
24

I got this confusion in one of my project as well and found this post, very helpful. Tried the same in my playground and here is the summary. Hope this helps someone with stored properties and functions of type static, final,class, overriding class vars etc.

class Simple {

    init() {print("init method called in base")}

    class func one() {print("class - one()")}

    class func two() {print("class - two()")}

    static func staticOne() {print("staticOne()")}

    static func staticTwo() {print("staticTwo()")}

    final func yesFinal() {print("yesFinal()")}

    static var myStaticVar = "static var in base"

    //Class stored properties not yet supported in classes; did you mean 'static'?
    class var myClassVar1 = "class var1"

    //This works fine
    class var myClassVar: String {
       return "class var in base"
    }
}

class SubSimple: Simple {
    //Successful override
    override class func one() {
        print("subClass - one()")
    }
    //Successful override
    override class func two () {
        print("subClass - two()")
    }

    //Error: Class method overrides a 'final' class method
    override static func staticOne() {

    }

    //error: Instance method overrides a 'final' instance method
    override final func yesFinal() {

    }

    //Works fine
    override class var myClassVar: String {
        return "class var in subclass"
    }
}

And here is the testing samples:

print(Simple.one())
print(Simple.two())
print(Simple.staticOne())
print(Simple.staticTwo())
print(Simple.yesFinal(Simple()))
print(SubSimple.one())
print(Simple.myStaticVar)
print(Simple.myClassVar)
print(SubSimple.myClassVar)

//Output
class - one()
class - two()
staticOne()
staticTwo()
init method called in base
(Function)
subClass - one()
static var in base
class var in base
class var in subclass
Akin answered 12/6, 2016 at 2:10 Comment(0)
A
13

Swift class vs static

[Reference vs Value Type]

class is used inside Reference Type(class, function):

  • computed property
  • method
  • can be overridden by subclass

static is used inside Reference Type(class, function) and Value Type(struct, enum, tuple):

  • computed property and stored property
  • method
  • cannot be changed by subclass
protocol MyProtocol {
//    class var protocolClassVariable : Int { get }//ERROR: Class properties are only allowed within classes
    static var protocolStaticVariable : Int { get }
    
//    class func protocolClassFunc()//ERROR: Class methods are only allowed within classes
    static func protocolStaticFunc()
}

struct ValueTypeStruct: MyProtocol {
    //MyProtocol implementation begin
    static var protocolStaticVariable: Int = 1
    
    static func protocolStaticFunc() {
        
    }
    //MyProtocol implementation end
    
//    class var classVariable = "classVariable"//ERROR: Class properties are only allowed within classes
    static var staticVariable = "staticVariable"

//    class func classFunc() {} //ERROR: Class methods are only allowed within classes
    static func staticFunc() {}
}

class ReferenceTypeClass: MyProtocol {
    //MyProtocol implementation begin
    static var protocolStaticVariable: Int = 2
    
    static func protocolStaticFunc() {
        
    }
    //MyProtocol implementation end
    
    var variable = "variable"

//    class var classStoredPropertyVariable = "classVariable"//ERROR: Class stored properties not supported in classes

    class var classComputedPropertyVariable: Int {
        get {
            return 1
        }
    }

    static var staticStoredPropertyVariable = "staticVariable"

    static var staticComputedPropertyVariable: Int {
        get {
            return 1
        }
    }

    class func classFunc() {}
    static func staticFunc() {}
}

final class FinalSubReferenceTypeClass: ReferenceTypeClass {
    override class var classComputedPropertyVariable: Int {
        get {
            return 2
        }
    }
    override class func classFunc() {}
}

//class SubFinalSubReferenceTypeClass: FinalSubReferenceTypeClass {}// ERROR: Inheritance from a final class

Altocumulus answered 8/12, 2019 at 15:11 Comment(0)
I
9

There's one more difference: class can be used to define type properties of computed type only. If you need a stored type property use static instead.

You define type properties with the static keyword. For computed type properties for class types, you can use the class keyword instead to allow subclasses to override the superclass’s implementation.

https://docs.swift.org/swift-book/LanguageGuide/Properties.html

Intangible answered 20/8, 2016 at 16:24 Comment(1)
man read carefully that article and compare with your "answer". You can use static for both computed and stored properties. The difference is use the class keyword instead to allow subclasses to override the superclass’s implementationAmplification
D
8

Adding to above answers static methods are static dispatch means the compiler know which method will be executed at runtime as the static method can not be overridden while the class method can be a dynamic dispatch as subclass can override these.

Dorelle answered 23/8, 2018 at 18:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.