协议组成相同 属性
Procotol composition on the same property
有办法实现吗?
protocol VCProtocol1: UIViewController {
var viewModel: VMProtocol1? { get set }
}
protocol VCProtocol2: UIViewController {
var viewModel: VMProtocol2? { get set }
}
class VC: UIViewController, VCProtocol1, VCProtocol2 {
var viewModel: (VMProtocol1 & VMProtocol2)?
}
我想做的是在 ViewController 上进行组合,以避免在多个 ViewController 中重新实现相同的代码。
编辑:
更准确地说,这里的问题是我希望我的 viewModel 属性 在两个协议之间共享,因为最终我想实现这样的东西:
- 查看模型
protocol VMProtocol1 {
func vmTest1()
}
protocol VMProtocol2 {
func vmTest2()
}
class ViewModel: VMProtocol1, VMProtocol2 {
func vmTest1() { }
func vmTest2() { }
}
- 视图控制器
protocol VCProtocol1: UIViewController {
var viewModel: VMProtocol1 { get set }
func vcTest1()
}
extension VCProtocol1 {
func vcTest1() {
// This is the key point, I want to be able to refer to my viewModel property internally in each protocol.
self.viewModel.vmTest1()
}
}
protocol VCProtocol2: UIViewController {
var viewModel: VMProtocol2 { get set }
}
class VC: UIViewController, VCProtocol1, VCProtocol2 {
var viewModel: (VMProtocol1 & VMProtocol2)?
}
这实际上是不可能的。在 Swift.
中根本不可能实现声明相同 属性(这里 viewModel
)但具有不同类型的多个协议的一个实体
最接近的做法是使用一种协议,将 viewModel 类型定义为关联类型并提供条件扩展(它将强制您使用通用实现)。
请注意,这是一个复杂的实现,需要对通用协议有很好的了解。我不建议在不完全了解你在做什么的情况下使用如此复杂的设计。
查看模型
protocol VMProtocol1 {
func vmTest1()
}
protocol VMProtocol2 {
func vmTest2()
}
class ViewModel: VMProtocol1, VMProtocol2 {
func vmTest1() { }
func vmTest2() { }
}
实施
protocol VCProtocolBase {
associatedtype ViewModel
var viewModel: ViewModel { get }
}
protocol VCProtocol1: VCProtocolBase {
func vmTest1()
}
protocol VCProtocol2: VCProtocolBase {
func vmTest2()
}
extension VCProtocolBase where Self: VCProtocol1, Self.ViewModel: VMProtocol1 {
func vmTest1() {
viewModel.vmTest1()
}
}
extension VCProtocolBase where Self: VCProtocol2, Self.ViewModel: VMProtocol2 {
func vmTest2() {
viewModel.vmTest2()
}
}
final class VC<ViewModel: VMProtocol1 & VMProtocol2>: VCProtocolBase, VCProtocol1, VCProtocol2 {
var viewModel: ViewModel
init(viewModel: ViewModel) {
self.viewModel = viewModel
}
}
VC(viewModel: ViewModel()).vmTest1()
VC(viewModel: ViewModel()).vmTest2()
这里的想法是依靠泛型和条件扩展来为VCProtocolX
提供默认实现,这就是VCProtocolBase
的作用。
有办法实现吗?
protocol VCProtocol1: UIViewController {
var viewModel: VMProtocol1? { get set }
}
protocol VCProtocol2: UIViewController {
var viewModel: VMProtocol2? { get set }
}
class VC: UIViewController, VCProtocol1, VCProtocol2 {
var viewModel: (VMProtocol1 & VMProtocol2)?
}
我想做的是在 ViewController 上进行组合,以避免在多个 ViewController 中重新实现相同的代码。
编辑:
更准确地说,这里的问题是我希望我的 viewModel 属性 在两个协议之间共享,因为最终我想实现这样的东西:
- 查看模型
protocol VMProtocol1 {
func vmTest1()
}
protocol VMProtocol2 {
func vmTest2()
}
class ViewModel: VMProtocol1, VMProtocol2 {
func vmTest1() { }
func vmTest2() { }
}
- 视图控制器
protocol VCProtocol1: UIViewController {
var viewModel: VMProtocol1 { get set }
func vcTest1()
}
extension VCProtocol1 {
func vcTest1() {
// This is the key point, I want to be able to refer to my viewModel property internally in each protocol.
self.viewModel.vmTest1()
}
}
protocol VCProtocol2: UIViewController {
var viewModel: VMProtocol2 { get set }
}
class VC: UIViewController, VCProtocol1, VCProtocol2 {
var viewModel: (VMProtocol1 & VMProtocol2)?
}
这实际上是不可能的。在 Swift.
中根本不可能实现声明相同 属性(这里viewModel
)但具有不同类型的多个协议的一个实体
最接近的做法是使用一种协议,将 viewModel 类型定义为关联类型并提供条件扩展(它将强制您使用通用实现)。
请注意,这是一个复杂的实现,需要对通用协议有很好的了解。我不建议在不完全了解你在做什么的情况下使用如此复杂的设计。
查看模型
protocol VMProtocol1 {
func vmTest1()
}
protocol VMProtocol2 {
func vmTest2()
}
class ViewModel: VMProtocol1, VMProtocol2 {
func vmTest1() { }
func vmTest2() { }
}
实施
protocol VCProtocolBase {
associatedtype ViewModel
var viewModel: ViewModel { get }
}
protocol VCProtocol1: VCProtocolBase {
func vmTest1()
}
protocol VCProtocol2: VCProtocolBase {
func vmTest2()
}
extension VCProtocolBase where Self: VCProtocol1, Self.ViewModel: VMProtocol1 {
func vmTest1() {
viewModel.vmTest1()
}
}
extension VCProtocolBase where Self: VCProtocol2, Self.ViewModel: VMProtocol2 {
func vmTest2() {
viewModel.vmTest2()
}
}
final class VC<ViewModel: VMProtocol1 & VMProtocol2>: VCProtocolBase, VCProtocol1, VCProtocol2 {
var viewModel: ViewModel
init(viewModel: ViewModel) {
self.viewModel = viewModel
}
}
VC(viewModel: ViewModel()).vmTest1()
VC(viewModel: ViewModel()).vmTest2()
这里的想法是依靠泛型和条件扩展来为VCProtocolX
提供默认实现,这就是VCProtocolBase
的作用。