¿Funciones/variables estáticas vs clase en clases Swift?


El siguiente código se compila en Swift 1.2:

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

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

¿Cuál es la diferencia entre una función estática y una función de clase? ¿Cuál debo usar y cuándo?

Si intento definir otra variable class var myVar2 = "", dice:

Class stored properties not yet supported in classes; ¿quiso decir 'static'?

Cuando se admite esta característica, cuál será la diferencia entre una variable estática y una variable clase (es decir, cuando ambos están definidos en una clase)? ¿Cuál debo usar y cuándo?

(Xcode 6.3)

Author: Senseful, 2015-04-14

7 answers

static y class ambos asocian un método con una clase, en lugar de una instancia de una clase. La diferencia es que las subclases pueden anular los métodos class; no pueden anular los métodos static.

class las propiedades funcionarán teóricamente de la misma manera (las subclases pueden sobrescribirlas), pero aún no son posibles en Swift.

 531
Author: mipadi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-14 20:23:34

Probé la respuesta y los comentarios de mipadi sobre playground. Y pensé en compartirlo. Aquí tienes. Creo que la respuesta de Mipadi debería ser "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(){

    }

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

    }
}
 52
Author: MadNik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-13 09:09:58

Con respecto a OOP , la respuesta es demasiado simple:

Las subclases pueden anular los métodos class, pero no pueden anular los métodos static.

Además de tu post, si quieres declarar una variable class (como hiciste class var myVar2 = ""), debes hacerlo de la siguiente manera:

class var myVar2: String {
    return "whatever you want"
}
 21
Author: eMdOS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-17 13:54:36

También tuve esta confusión en uno de mis proyectos y encontré este post muy útil. Intenté lo mismo en mi patio de recreo y aquí está el resumen. Espero que esto ayude a alguien con propiedades almacenadas y funciones de tipo static, final,class, sobreescribiendo vars de clase, 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"
    }
}

Y aquí están las muestras de prueba:

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
 19
Author: Santosh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-22 19:42:09

Las pruebas en Swift 4 muestran diferencias de rendimiento en el simulador. Hice una clase con " class func "y struct con" static func " y los ejecuté en prueba.

Func estático es:

  • 20% más rápido sin optimización del compilador
  • 38% más rápido cuando optimización-todo-módulo-optimización está habilitado.

Sin embargo, ejecutar el mismo código en iPhone 7 bajo iOS 10.3 muestra exactamente el mismo rendimiento.

Aquí está un proyecto de ejemplo en Swift 4 para Xcode 9 si te gusta probarte a ti mismo https://github.com/protyagov/StructVsClassPerformance

 13
Author: Alex Protyagov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-22 18:59:27

Hay una diferencia más. class se puede usar para definir las propiedades de tipo de solo el tipo calculado. Si necesita una propiedad de tipo almacenado use static en su lugar.

"Se definen las propiedades de tipo con la palabra clave estática. Para las propiedades de tipo computado para tipos de clase, puede usar la palabra clave class en su lugar para permitir que las subclases anulen la implementación de la superclase."

 4
Author: Maciek Czarnik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-20 16:24:19

Agregar a las respuestas anteriores los métodos estáticos son envío estático significa que el compilador sabe qué método se ejecutará en tiempo de ejecución, ya que el método estático no se puede sobreescribir, mientras que el método de clase puede ser un envío dinámico, ya que la subclase puede sobreescribirlos.

 0
Author: Ankit garg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-23 18:54:20