我想以某种方式实现主题,功能可以将其所需的颜色添加到主题协议中,这样任何实际的主题实现都必须为每个功能提供颜色。我还希望将主题实现和功能主题要求放在单独的文件中。如果我将主题或功能移动到另一个项目中,我不想手动删除代码行。
import UIKit
protocol Theme {
static var genericColor: UIColor { get }
}
protocol FeatureTheme {
static var featureColor: UIColor { get }
}
extension Theme {
static var feature: FeatureTheme.Type! {
return nil
}
}
struct LightTheme: Theme {
static var genericColor: UIColor { return .white }
static var feature: FeatureTheme.Type! { return Feature.self }
struct Feature: FeatureTheme {
static var featureColor: UIColor { return UIColor.red }
}
}
let currentTheme: Theme.Type = LightTheme.self
print(currentTheme) // LightTheme
print(currentTheme.feature.featureColor) // error, because feature is nil
所以,我想通过扩展将FeatureTheme要求添加到Theme协议中。 Swift希望在协议扩展中看到默认实现。我想在实际的LightTheme实现中“覆盖”它,但这不起作用。该物业仍然返回零。我该如何解决这个问题?
答案 0 :(得分:1)
你做的是正确的,但如果你观察你的代码
let currentTheme: Theme.Type = LightTheme.self
currentTheme
的类型为Theme
,但您已分配LightTheme
,现在为Theme
且已在您的协议中
extension Theme {
static var feature: FeatureTheme.Type! {
return nil
}
}
您已将[{1}}作为默认实施方式返回,因为nil
为currentTheme
类型不是Theme
,并且不需要正确
使用当前实现解决方案再次简单就是将LightTheme
声明为currentTheme
请参阅下面的答案
LightTheme
OR
保持let currentTheme: LightTheme.Type = LightTheme.self
只需指定currentTheme
,如下所示
LightTheme
希望它对你有所帮助
输出:
LightTheme UIExtendedSRGBColorSpace 1 0 0 1
答案 1 :(得分:1)
Theme
的扩展名不会对协议添加任何要求,只是将计算出的静态属性添加到Theme.Type
类型的任何内容中。因此,对于任何feature
的内容,您都不能覆盖Theme.Type
的默认实现。只有当feature
是协议的实际要求时才会出现这种情况。也许是这样的:
protocol Theme {
static var feature: FeatureTheme.Type { get }
static var genericColor: UIColor { get }
}
protocol FeatureTheme {
static var featureColor: UIColor { get }
}
struct LightTheme: Theme {
static var genericColor: UIColor { return .white }
static var feature: FeatureTheme.Type { return Feature.self }
struct Feature: FeatureTheme {
static var featureColor: UIColor { return UIColor.red }
}
}
let currentTheme: Theme.Type = LightTheme.self
print(currentTheme) // "LightTheme"
print(currentTheme.feature.featureColor) // "UIExtendedSRGBColorSpace 1 0 0 1"
然后也不需要feature
是可选的并且强制解包。
答案 2 :(得分:1)
对于评论中的误解,我们深表歉意
这有两个解决方案:
这是@Prashant Tukadiya的回答。将currentTheme
声明为LightTheme
但是,我认为,出于某种原因,你需要使它Theme.type
。因此,将feature
声明为Theme
协议的属性,可以(应该)被覆盖。
protocol Theme {
static var genericColor: UIColor { get }
static var feature: FeatureTheme.Type! { get }
}
如果您不这样做,Theme.feature
的定义只是Theme
的静态属性。然后,LightTheme.feature
不会从Theme
继承。如果你这样做,Theme.feature
可以(应该)在子类中实现。您在Theme
的扩展名中定义了默认实现,也可以覆盖它。