Swift 从对象读取静态属性

Swift 从对象读取静态属性,swift,Swift,我有一个具有静态属性的类,我想为特定对象访问该类。代码如下: import UIKit protocol Theme { static var name: String { get } func getBackgroundColor() -> UIColor } class DefaultTheme: Theme { static var name = "Default theme" func getBackgroundColor() -> U

我有一个具有静态属性的类,我想为特定对象访问该类。代码如下:

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配合使用)

您在Swift 1.2中遇到了一个模糊且非常有趣的错误。Swift有着与协议所需的静态变量相关的bug的悠久历史,这似乎是另一个bug

显然,这里的问题是,您试图将基于协议的特征与基于类的特征混合匹配。假设你说过:

var currentTheme = DefaultTheme()
然后,
currentTheme
将被键入DefaultTheme——一个类的实例。这意味着您可以通过传递该实例的
dynamicType
来访问该实例中的类成员:

println(currentTheme.dynamicType.name) // "Default theme"
但是您不能在代码中这样做,因为您已经键入了
currentTheme
作为主题-协议:

var currentTheme : Theme = DefaultTheme()
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"
这对协议强加的
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)
即使在协议中也能完美工作:

var currentTheme : Theme = DefaultTheme()
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"