静态与 class functions/variables 在 Swift class 中?
Static vs class functions/variables in Swift classes?
以下代码在 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 = ""
,它会显示:
Class stored properties not yet supported in classes; did you mean 'static'?
支持此功能后,static 变量和 class 变量(即当两者都在 class 中定义时?我应该使用哪一个,什么时候使用?
(Xcode6.3)
static
和 class
都将方法与 class 相关联,而不是 class 的实例。区别在于subclasses可以覆盖class
方法;他们不能覆盖 static
方法。
class
属性在理论上将以相同的方式运行(subclasses 可以覆盖它们),但它们在 Swift 中是不可能的。
关于OOP,答案太简单了:
subclasses可以覆盖class方法,但不能覆盖static方法。
除了你的 post,如果你想声明一个 class 变量(就像你做的 class var myVar2 = ""
),你应该做如下:
class var myVar2: String {
return "whatever you want"
}
我在 playground 上尝试了 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(){
}
//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(){
}
}
我在我的一个项目中也遇到了这种困惑,发现这个 post 非常有帮助。在我的操场上尝试了同样的方法,这里是总结。希望这可以帮助具有 static
、final
、class
类型的存储属性和函数的人,覆盖 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"
}
}
这是测试样本:
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
。
You define type properties with the static keyword. For computed type properties for class types, you can use the class keyword instead to allow subclasses to override the superclass’s implementation.
https://docs.swift.org/swift-book/LanguageGuide/Properties.html
Swift4 中的测试显示了模拟器中的性能差异。我在测试中用 "class func" 做了一个 class 并用 "static func" 和 运行 构造了它们。
静态函数是:
- 20% 在没有编译器优化的情况下更快
- 38% 启用优化-whole-module-optimization 时速度更快。
然而,运行 iPhone 7 上的相同代码在 iOS 10.3 下显示完全相同的性能。
这里是 Swift 4 中 Xcode 9 的示例项目,如果你想测试自己的话
https://github.com/protyagov/StructVsClassPerformance
添加到上述答案中,静态方法是静态调度意味着编译器知道将在运行时执行哪个方法,因为静态方法不能被覆盖,而 class 方法可以是动态调度,因为 subclass 可以覆盖这些。
Swift class 对比静态
[Reference vs Value Type]
class
内部使用Reference Type
(class,函数):
- 计算属性
- 方法
- 可以被subclass
覆盖
static
用于 Reference Type
(class, function) 和 Value Type
(struct, enum, tuple):
- 计算 属性 并存储 属性
- 方法
- 不能被subclass
改变
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
以下代码在 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 = ""
,它会显示:
Class stored properties not yet supported in classes; did you mean 'static'?
支持此功能后,static 变量和 class 变量(即当两者都在 class 中定义时?我应该使用哪一个,什么时候使用?
(Xcode6.3)
static
和 class
都将方法与 class 相关联,而不是 class 的实例。区别在于subclasses可以覆盖class
方法;他们不能覆盖 static
方法。
class
属性在理论上将以相同的方式运行(subclasses 可以覆盖它们),但它们在 Swift 中是不可能的。
关于OOP,答案太简单了:
subclasses可以覆盖class方法,但不能覆盖static方法。
除了你的 post,如果你想声明一个 class 变量(就像你做的 class var myVar2 = ""
),你应该做如下:
class var myVar2: String {
return "whatever you want"
}
我在 playground 上尝试了 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(){
}
//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(){
}
}
我在我的一个项目中也遇到了这种困惑,发现这个 post 非常有帮助。在我的操场上尝试了同样的方法,这里是总结。希望这可以帮助具有 static
、final
、class
类型的存储属性和函数的人,覆盖 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"
}
}
这是测试样本:
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
。
You define type properties with the static keyword. For computed type properties for class types, you can use the class keyword instead to allow subclasses to override the superclass’s implementation.
https://docs.swift.org/swift-book/LanguageGuide/Properties.html
Swift4 中的测试显示了模拟器中的性能差异。我在测试中用 "class func" 做了一个 class 并用 "static func" 和 运行 构造了它们。
静态函数是:
- 20% 在没有编译器优化的情况下更快
- 38% 启用优化-whole-module-optimization 时速度更快。
然而,运行 iPhone 7 上的相同代码在 iOS 10.3 下显示完全相同的性能。
这里是 Swift 4 中 Xcode 9 的示例项目,如果你想测试自己的话 https://github.com/protyagov/StructVsClassPerformance
添加到上述答案中,静态方法是静态调度意味着编译器知道将在运行时执行哪个方法,因为静态方法不能被覆盖,而 class 方法可以是动态调度,因为 subclass 可以覆盖这些。
Swift class 对比静态
[Reference vs Value Type]
class
内部使用Reference Type
(class,函数):
- 计算属性
- 方法
- 可以被subclass 覆盖
static
用于 Reference Type
(class, function) 和 Value Type
(struct, enum, tuple):
- 计算 属性 并存储 属性
- 方法
- 不能被subclass 改变
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