function type Funções/variáveis de classe estática vs nas classes Swift?




swift is (6)

O código a seguir compila no Swift 1.2:

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

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

Qual é a diferença entre uma função estática e uma função de classe ? Qual deles devo usar e quando?

Se eu tentar definir outra class var myVar2 = "" variável class var myVar2 = "" , ele diz:

Propriedades armazenadas de classe ainda não suportadas em classes; você quis dizer 'estática'?

Quando este recurso é suportado, qual será a diferença entre uma variável estática e uma variável de classe (ou seja, quando ambas são definidas em uma classe)? Qual deles devo usar e quando?

(Xcode 6.3)


Eu tentei a resposta do mipadi e comentários no playground. E pensei em compartilhá-lo. Aqui está. Eu acho que a resposta do mipadi deve ser marcada como aceita.

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

    }

    //Lets 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(){

    }
}

O teste no Swift 4 mostra a diferença de desempenho no simulador. Eu fiz uma classe com "classe func" e struct com "static func" e os testei.

função estática é:

  • 20% mais rápido sem otimização do compilador
  • 38% mais rápido quando a otimização -whole-module-optimization está ativada.

No entanto, a execução do mesmo código no iPhone 7 do iOS 10.3 mostra exatamente o mesmo desempenho.

Aqui está um exemplo de projeto no Swift 4 para o Xcode 9 se você quiser se testar https://github.com/protyagov/StructVsClassPerformance


Somando-se as respostas acima, métodos estáticos são despacho estático significa que o compilador sabe qual método será executado em tempo de execução, pois o método estático não pode ser substituído enquanto o método da classe pode ser um despacho dinâmico, pois a subclasse pode sobrescrevê-los.


Eu tenho essa confusão em um dos meus projetos também e achei este post muito útil. Tentei o mesmo no meu playground e aqui está o resumo. Espero que isso ajude alguém com propriedades armazenadas e funções do tipo static , final , class , substituindo classe 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"
    }
}

E aqui estão as amostras de teste:

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

Quanto à OOP , a resposta é simples demais:

As subclasses podem substituir métodos de classe , mas não podem substituir métodos estáticos .

Além do seu post, se você quiser declarar uma variável de classe (como você fez class var myVar2 = "" ), você deve fazer da seguinte forma:

class var myVar2: String {
    return "whatever you want"
}





static