静态vs类函数/变量在Swift类?

以下代码在Swift 1.2中编译:

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


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

静态函数和函数的区别是什么?我应该用哪一个,什么时候用?

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

类中还不支持类存储属性;你是说“静电”吗?

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

(Xcode 6.3)

185448 次浏览

staticclass都将方法关联到类,而不是类的实例。区别在于子类可以覆盖class方法;它们不能覆盖static方法。

class属性理论上将以相同的方式运行(子类可以覆盖它们),但在Swift中还不可能。

关于OOP,答案太简单了:

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

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

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

我在操场上尝试了米帕迪的回答和评论。我想分享它。给你。我认为米帕迪的回答应该被认可。

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

}
}

我在我的一个项目中也有这种困惑,我发现这篇文章非常有用。在我的操场上也试过,下面是总结。希望这有助于存储属性和函数类型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

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

使用static关键字定义类型属性。对于类类型的计算类型属性,可以使用class关键字来允许子类重写超类的实现。

https://docs.swift.org/swift-book/LanguageGuide/Properties.html

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

静态函数是:

  • 20%更快没有编译器优化
  • 当optimize -whole-module-optimization被启用时,38%更快。

然而,在iOS 10.3下的iPhone 7上运行相同的代码显示出完全相同的性能。

如果你喜欢自己测试的话,这里是Swift 4的Xcode 9的示例项目 https://github.com/protyagov/StructVsClassPerformance < / p >

添加到上述答案的静态方法是静态分派意味着编译器知道哪个方法将在运行时执行,因为静态方法不能被覆盖,而类方法可以是动态分派,因为子类可以覆盖这些方法。

Swift类vs静态类

[参考vs值类型] . > .

classReference Type(类,函数)中使用:

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

staticReference Type(类,函数)和Value Type(结构,enum,元组)中使用:

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