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

ygya80vv  于 2023-01-04  发布在  Swift
关注(0)|答案(8)|浏览(128)

以下代码在Swift 1.2中编译:

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

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

static函数和class函数有什么区别?我应该使用哪一个,什么时候使用?

如果我尝试定义另一个变量class var myVar2 = "",它会说:
类中尚不支持类存储属性;你是说“静电”吗?
当这个特性被支持时,static变量和class变量之间的区别是什么(即当两者都在类中定义时)?我应该使用哪一个,什么时候使用?
( xcode 6.3)

new9mtju

new9mtju1#

staticclass都是将方法与类相关联,而不是与类的示例相关联,区别在于子类可以覆盖class方法;它们不能覆盖static方法。
class属性的作用方式相同(子类可以覆盖它们)。

hs1ihplo

hs1ihplo2#

我试了一下mipadi的回答和在playground上的评论。并且想到了分享它。给你。我认为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(){
        
    }
    
    //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(){
        
    }
}
xzlaal3s

xzlaal3s3#

关于OOP,答案太简单了:
子类可以覆盖class方法,但不能覆盖static方法。
除了你的文章之外,如果你想声明一个class变量(就像你声明class var myVar2 = ""一样),你应该按如下所示做:

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

lf3rwulv4#

Swift 4中的测试显示了模拟器中的性能差异。我用“class func”创建了一个类,用“static func”创建了一个结构,并在测试中运行了它们。
静态函数为:

***20%**的速度,无需编译器优化
***38%**当优化-整个模块-优化被启用时。

然而,在iOS 10. 3下的iPhone 7上运行相同的代码,表现出完全相同的性能。
如果你想测试自己https://github.com/protyagov/StructVsClassPerformance,这里是Swift 4中Xcode 9的示例项目

cnh2zyt3

cnh2zyt35#

我在我的一个项目中也遇到了这个困惑,发现这个帖子很有帮助。在我的操场上也试过了,这里是总结。希望这能帮助一些人处理staticfinalclass类型的存储属性和函数,覆盖类变量等。

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

这是测试样本:

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
wi3ka0sx

wi3ka0sx6#

Swift类与静态

Reference vs Value Type(https://stackoverflow.com/a/59219141/4770877)
classReference Type内部使用(类、函数):

  • 计算性质
  • 方法
    *是否可以被子类覆盖

staticReference Type(类、函数)和Value Type(结构、枚举、元组)内部使用:

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

zxlwwiss7#

还有一点不同class只能用于定义计算类型的类型属性。如果需要存储类型属性,请改用static
可以使用static关键字定义类型属性。对于类类型的计算类型属性,可以改用class关键字以允许子类重写超类的实现。
https://docs.swift.org/swift-book/LanguageGuide/Properties.html

axzmvihb

axzmvihb8#

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

相关问题