从对象

时间:2015-06-13 21:10:45

标签: swift

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

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)

1 个答案:

答案 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"