2015-06-13 5 views
3

У меня есть класс со статическим свойством, к которому я хотел бы получить доступ для определенного объекта. Код выглядит следующим образом:Прочитать статическое свойство из объекта

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' 

Я не могу Acces имени Тематического с помощью DefaultTheme.name потому currentTheme может быть экземпляром другого класса Theme, но мне нужно знать его имя. Как я могу получить доступ к этой статической переменной?

Я использую Xcode 6.3.1 (с Swift 1.2)

ответ

4

Вы попали неясного и очень интересный баг в Swift 1.2. Swift имеет долгую историю ошибок, связанных со статическими переменными, требуемыми протоколами, и это, похоже, является еще одним.

Проблема здесь, по-видимому, в том, что вы пытались смешивать и сопоставлять характеристики на основе протокола с характеристиками на основе классов. Предположим, что вы сказали это:

var currentTheme = DefaultTheme() 

Тогда currentTheme будет набран как DefaultTheme - экземпляр класса. Это означает, что вы можете получить доступ к члену класса из экземпляра пропускания через в dynamicType этого экземпляра:

println(currentTheme.dynamicType.name) // "Default theme" 

Но вы не можете сделать это в вашего кода, потому что вы набрали currentTheme как тему - протокол:

var currentTheme : Theme = DefaultTheme() 

Это делает странные вещи к понятию name имущества, которое налагается протоколом, и поэтому вы не можете получить доступ к name собственности вообще.

У вас не возникло проблемы, если Тема была 0Телефонный суперкласс. В этом случае вы можете использовать свойство класса (которое должно быть вычисленным свойством), и оно будет работать полиморфно. В 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" 
Смежные вопросы