[英]How to resolve generic property in protocol with associatedtype?
Idea is to share the common code between UITableView
and UICollectionView
and their viewModels.想法是在UITableView
和UICollectionView
及其视图模型之间共享公共代码。 So I have a baseCollectionsViewModel which is a generic class and looks like所以我有一个 baseCollectionsViewModel 它是一个通用的 class 看起来像
class BaseCollectionsViewModel<T: BasicTrackDataExtractorProtocol> {
var baseTrackResponse: T?
...
}
Now I would like to have a BaseCollectionsView
which holds BaseCollectionsViewModel
.现在我想要一个包含BaseCollectionsView
的BaseCollectionsViewModel
。 Because its a UITableView
and UICollectionView
I cant have a common base class among them so I decided to go in the direction of protocol to work around multiple inheritance Because its a UITableView
and UICollectionView
I cant have a common base class among them so I decided to go in the direction of protocol to work around multiple inheritance
protocol BaseCollectionsViewProtocol {
associatedtype dataExtractorType: BasicTrackDataExtractorProtocol
var viewModel: BaseCollectionsViewModel<dataExtractorType>! { get }
//all other common properties and logic here
}
Finally when I try to use this protocol in my final class最后,当我尝试在我的最终 class 中使用此协议时
final class TrackingTableViewModel: BaseCollectionsViewModel<TrackOrderV3> {
}
final class TrackingTableView: UITableView,BaseCollectionsViewProtocol {
var viewModel: TrackingTableViewModel!
typealias dataExtractorType = TrackOrderV3
//other code
}
Compiler complains that TrackingTableView
does not confirm to BaseCollectionsViewProtocol
and keeps adding编译器抱怨TrackingTableView
没有向BaseCollectionsViewProtocol
确认并不断添加
final class TrackingTableView: UITableView,BaseCollectionsViewProtocol {
var viewModel: BaseCollectionsViewModel<TrackOrderV3>!
typealias dataExtractorType = TrackOrderV3
Is this because BaseCollectionsViewModel<TrackOrderV3>
and TrackingTableViewModel
are invariant?这是因为BaseCollectionsViewModel<TrackOrderV3>
和TrackingTableViewModel
是不变的吗? Is there anyway I can resolve this problem with TypeErasure
?无论如何我可以用TypeErasure
解决这个问题吗?
If its not a protocol I could solve it as如果它不是协议,我可以将其解决为
class TestTableView<T: BasicTrackDataExtractorProtocol, U: BaseCollectionsViewModel<T>> {
var viewModel: U!
}
class TestTrackingTableView: TestTableView<TrackOrderV3, TrackingTableViewModel> {
func testViewModel() {
let _ = self.viewModel.numberOfRows
}
}
But the issue is now I cant say class TestTrackingTableView: TestTableView<TrackOrderV3, TrackingTableViewModel>, UITableView
because multiple inheritance is not allowed.但问题是现在我不能说class TestTrackingTableView: TestTableView<TrackOrderV3, TrackingTableViewModel>, UITableView
因为多个 Z5FED3411FAF832174EF1F040028B2C21 是不允许的。
PS: Sorry for the highly confusing title, couldn't come up with a better title, will change if someone can suggest a better one:) PS:抱歉标题很混乱,想不出更好的标题,如果有人能推荐一个更好的,会改变的:)
What I would do is define a protocol for your view model:我要做的是为您的视图 model 定义一个协议:
protocol CollectionsViewModel {
associatedtype DataType: BasicTrackDataExtractorProtocol
var baseTrackResponse: DataType? { get }
}
Then implement a generic view model class that houses all of your common logic:然后实现一个包含所有常见逻辑的通用视图 model class:
class BaseCollectionsViewModel<T: BasicTrackDataExtractorProtocol>: CollectionsViewModel {
typealias DataType = T
var baseTrackResponse: T?
}
Rather than setting the data model as a type constraint on the view protocol set the view model as a type constraint.与其将数据 model 设置为视图协议的类型约束,不如将视图 model 设置为类型约束。 This will give us greater flexibility down the road.这将为我们提供更大的灵活性。
protocol BaseCollectionsViewProtocol {
associatedtype ViewModelType: CollectionsViewModel
var viewModel: ViewModelType! { get }
}
Now we can implement our final classes:现在我们可以实现我们的最终类:
final class TrackingTableViewModel: BaseCollectionsViewModel<TrackOrderV3> {
}
final class TrackingTableView: UITableView, BaseCollectionsViewProtocol {
var viewModel: TrackingTableViewModel!
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.