Swift类中的静态vs类函数/变量?

Sen*_*ful 398 variables static class function swift

以下代码在Swift 1.2中编译:

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

func doSomething() {
    myClass.myMethod1()
    myClass.myMethod2()
    myClass.myVar1 = "abc"
}
Run Code Online (Sandbox Code Playgroud)

静态函数和函数有什么区别?我应该使用哪一个,何时使用?

如果我尝试定义另一个变量class var myVar2 = "",它会说:

类中尚未支持的类存储属性; 你的意思是'静态'吗?

当支持这个特性时,静态变量和变量之间的区别是什么(即两者都是在类中定义的)?我应该使用哪一个,何时使用?

(Xcode 6.3)

mip*_*adi 657

static并且class都将方法与类相关联,而不是将类的实例相关联.不同之处在于子类可以覆盖class方法; 他们无法覆盖static方法.

class 属性在理论上将以相同的方式起作用(子类可以覆盖它们),但它们在Swift中是不可能的.

  • 那么类中的`final class`函数和'static'函数有什么区别? (86认同)
  • @hippo_san,在基类中,两者在功能上是相同的.但是,`final`可用于在子类中使用时切断进一步的覆盖.这两个都有它们的位置,我会说在类函数上使用时使用`static`或`final`是微不足道的,取决于你的风格选择. (52认同)
  • 啊,所以Swift中的`static func foo(){}`就像Java中的`public static final foo(){}` (7认同)
  • @Supuhstar:基本上,是的. (3认同)
  • @mipadi我现在明白了.对于类函数,我们可以将"static"替换为"final class",但对于类中的属性,我们只能使用静态属性而不是类属性.所以"静态"关键字仍然有其自己的位置. (2认同)

Mad*_*Nik 67

我在操场上尝试了mipadi的回答和评论.并想到分享它.干得好.我认为mipadi的回答应该标记为已被接受.

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

    }
}
Run Code Online (Sandbox Code Playgroud)


eMd*_*dOS 23

关于OOP,答案太简单了:

子类可以覆盖方法,但不能覆盖静态方法.

除了你的帖子,如果你想声明一个变量(就像你做的那样class var myVar2 = ""),你应该这样做:

class var myVar2: String {
    return "whatever you want"
}
Run Code Online (Sandbox Code Playgroud)


San*_*osh 22

我在我的一个项目中也遇到了这个困惑,发现这篇文章非常有帮助.在我的操场上尝试过同样的事情,这是摘要.希望这可以帮助别人与存储性能和类型的功能static,final,class,覆盖类乏等.

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"
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是测试样本:

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
Run Code Online (Sandbox Code Playgroud)


Ale*_*gov 19

Swift 4中的测试显示了模拟器中的性能差异.我创建了一个带有"class func"的类和带有"static func"的struct,并在测试中运行它们.

static func是:

  • 没有编译器优化,速度快20%
  • 启用优化 - 全模块优化时,速度提高38%.

但是,在iOS 10.3下在iPhone 7上运行相同的代码会显示完全相同的性能.

如果您想测试自己,可以使用Swift 4中的Xcode 9示例项目 https://github.com/protyagov/StructVsClassPerformance


Mac*_*nik 7

还有一个区别.class可用于定义计算类型的类型属性.如果你需要一个存储类型属性的使用static来代替.

"您使用static关键字定义类型属性.对于类类型的计算类型属性,您可以使用class关键字来允许子类覆盖超类的实现."


yoA*_*ex5 7

类与静态

[引用 vs 值类型]

class用于内部Reference Type(类,函数):

  • 计算属性
  • 方法
  • 可以被子类覆盖

staticReference Type(class, function) 和Value Type(struct, enum, tuple) 中使用:

  • 计算属性和存储属性
  • 方法
  • 子类不能改变
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

Run Code Online (Sandbox Code Playgroud)


Ank*_*arg 6

除上述方法外,静态方法是静态调度,这意味着编译器知道在运行时将执行哪种方法,因为静态方法不能被覆盖,而类方法可以是动态调度,因为子类可以覆盖这些方法。