我有一个带有静态属性的类,我想为特定对象访问它。代码如下:
import UIKit
protocol Theme {
static var name: String { get }
func getBackgroundColor() -> UIColor
}
class DefaultTheme: Theme {
static var name = "Default theme"
func getBackgroundColor() -> UIColor {
return UIColor.blackColor()
}
}
var currentTheme: Theme = DefaultTheme()
println(currentTheme.name) //Error: 'Theme' does not have a member named 'name'
我无法通过DefaultTheme.name
访问主题的名称,因为currentTheme
可能是不同主题类的实例,但我确实需要知道它的名称。如何访问此静态变量?
我正在使用Xcode 6.3.1(使用Swift 1.2)
答案 0 :(得分:4)
你在Swift 1.2中遇到了一个模糊且非常有趣的错误。 Swift与协议所需的静态变量相关的bug有很长的历史,这似乎是另一个。
显然,这里的问题是您尝试将基于协议的特性与基于类的特征混合和匹配。假设你说过这个:
var currentTheme = DefaultTheme()
然后currentTheme
将被输入为DefaultTheme - 类的实例。这意味着您可以通过传递该实例的dynamicType
来访问实例中的类成员:
println(currentTheme.dynamicType.name) // "Default theme"
但你不能在你的代码中这样做,因为你已经输入currentTheme
作为主题 - 协议:
var currentTheme : Theme = DefaultTheme()
这对于name
属性的概念很奇怪,这是由协议强加的,因此您根本无法访问name
属性。
如果Theme是DefaultTheme的超类,则不会出现此问题。在这种情况下,您可以使用类属性(必须是计算属性),它将以多态方式工作。在Swift 1.2中,这可能是你最好的选择:
class Theme {
class var name : String { return "Theme" }
}
class DefaultTheme: Theme {
override class var name : String { return "Default theme" }
}
var currentTheme : Theme = DefaultTheme()
println(currentTheme.dynamicType.name) // "Default theme"
另一方面,当您升级到Swift 2时,您会发现错误已得到修复,因此print(currentTheme.dynamicType.name)
即使使用协议也能正常运行:
protocol Theme {
static var name : String { get }
}
class DefaultTheme: Theme {
static var name = "Default theme"
}
var currentTheme : Theme = DefaultTheme()
print(currentTheme.dynamicType.name) // "Default theme"