Reading a static property of an object

I have a class with a static property that I would like to access for a specific object. The code is as follows:

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' 

I cannot get the topic name via DefaultTheme.name , because currentTheme may be an instance of another Theme class, but I need to know its name. How can I access this static variable?

I am using Xcode 6.3.1 (with Swift 1.2)

+3
swift
source share
1 answer

You got into an obscure and very interesting bug in Swift 1.2. Swift has a long history of errors related to the static variables required by the protocols, and it looks like another.

The problem here seems to be that you were trying to mix and match protocol-based characteristics with class-based characteristics. Suppose you said this:

 var currentTheme = DefaultTheme() 

Then currentTheme will be typed as DefaultTheme - an instance of the class. This means that you can access a class member from an instance by going through the dynamicType that instance:

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

But you cannot do this in your code because you typed currentTheme as the subject - protocol:

 var currentTheme : Theme = DefaultTheme() 

This does strange things to the concept of the name property, which is superimposed by the protocol, and therefore you cannot access the name property at all.

You would not have this problem if the theme were superclasses of DefaultTheme. In this case, you can use a class property (which should be a computed property), and it will work polymorphically. In Swift 1.2, this might be your best bet:

 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" 

On the other hand, when upgrading to Swift 2, you will find that the error is fixed, and therefore print(currentTheme.dynamicType.name) works fine even with the protocol:

 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" 
+4
source share

All Articles