ChatGPT解决这个技术问题 Extra ChatGPT

Static vs class functions/variables in Swift classes?

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)

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-swift

m
mipadi

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 will theoretically function in the same way (subclasses can override them), but they're not possible in Swift yet.


So what is the difference between final class function and 'static' function within a class?
@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.
ah, so static func foo(){} in Swift is like public static final foo(){} in Java?
@Supuhstar: Basically, yes.
@mipadi 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.
A
Alex Zavatone

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(){
        
    }
}

e
eMdOS

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"
}

A
Alex Protyagov

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


was this on the simulator or physical device?
n
nburk

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

y
yoAlex5

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


g
garg

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.


p
pkamb

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


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 implementation