以下代码在 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)
我尝试了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(){
}
}
关于OOP,答案太简单了:
子类可以重写class方法,但不能重写static方法。
除了您的帖子之外,如果您想声明一个 class 变量(就像您所做的
class var myVar2 = ""
一样),您应该按以下步骤操作:
class var myVar2: String {
return "whatever you want"
}
Swift 4 中的测试显示模拟器中的性能差异。我用“class func”创建了一个类,用“static func”创建了一个结构,并在测试中运行它们。
静态函数是:
但是,在 iOS 10.3 下的 iPhone 7 上运行相同的代码显示出完全相同的性能。
如果您想自己测试一下,这里是 Xcode 9 的 Swift 4 示例项目 https://github.com/protyagov/StructVsClassPerformance
我在我的一个项目中也遇到了这种困惑,发现这篇文章非常有帮助。在我的操场上尝试了同样的方法,这是总结。希望这对具有
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"
}
}
这是测试样本:
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
Swift 类与静态
class
用在Reference Type
(类,函数)中:
static
用于 Reference 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
还有一个区别:
class
只能用于定义计算类型的类型属性。如果您需要 存储类型属性,请使用 static
代替。
您可以使用 static 关键字定义类型属性。对于类类型的计算类型属性,您可以使用 class 关键字来允许子类覆盖超类的实现。
https://docs.swift.org/swift-book/LanguageGuide/Properties.html
添加到上面的答案静态方法是静态分派意味着编译器知道在运行时将执行哪个方法,因为静态方法不能被覆盖,而类方法可以是动态分派,因为子类可以覆盖这些方法。
这里有一些区别
静态 ->
1- Type-Specific:属于类型本身,不属于任何实例。
2- Non-Overridable:静态属性和方法不能被子类覆盖。
3- 内存分配:整个类型仅存在一份副本,在所有实例之间共享。
4- 用法:用于定义在该类型的所有实例中应保持一致且不变的常量、实用方法和属性。
5-在静态中我们可以使用计算属性和存储属性。
1- Type-Specific:属于类型本身,不属于任何实例。
2- 可重写:类属性(必须计算)和方法可以被子类重写。
3- 内存分配:整个类型仅存在一份副本,在所有实例之间共享。
4 用法:用于定义子类中可能需要自定义或扩展的属性和方法。