【发布时间】:2018-09-07 10:19:30
【问题描述】:
我面临使用泛型类和继承的问题。
问题的简要描述:
我有一个名为BookPageDataSource 的基类和两个具有不同实现的继承类(ReadingBookPageDataSource 和StarsBookPageDataSource)。
另外,我有一个泛型类BookPageViewController,它包含这个数据源的泛型参数和从这个类继承的两个类(ReadingBookPageViewController 和StarsBookPageViewController)。
我需要写一个返回参数为BookPageViewController<DataSource>的方法。
// Data Sources
class BookPageDataSource { }
class ReadingBookPageDataSource: BookPageDataSource { }
class StarsBookPageDataSource: BookPageDataSource { }
// Controllers
class BookPageViewController<DataSource: BookPageDataSource>: UIViewController {
let dataSource: DataSource
init(dataSource: DataSource) {
self.dataSource = dataSource
super.init(nibName: nil, bundle: nil)
}
required init?(coder aDecoder: NSCoder) {
return nil
}
}
final class ReadingBookPageViewController: BookPageViewController<ReadingBookPageDataSource> { }
final class StarsBookPageViewController: BookPageViewController<StarsBookPageDataSource> { }
// Communication
class Pager {
func currentPageController<DataSource>(at index: Int) -> BookPageViewController<DataSource> {
// for example
if index == 0 {
// How to remove the cast from the line below?
return readingPageController() as! BookPageViewController<DataSource>
}
return starsPageController() as! BookPageViewController<DataSource>
}
private func readingPageController() -> ReadingBookPageViewController {
return ReadingBookPageViewController(dataSource: ReadingBookPageDataSource())
}
private func starsPageController() -> StarsBookPageViewController {
return StarsBookPageViewController(dataSource: StarsBookPageDataSource())
}
}
方法currentPageController 总是崩溃,因为DataSource 总是等于BookPageDataSource,而不是ReadingBookPageDataSource 或StarsBookPageDataSource。
【问题讨论】:
-
也许你需要类型擦除。
-
你真的需要
BookPageDataSource来上课吗?您是否考虑过它只是一个协议的情况?这样你就可以在 VC 的 init 方法中进行依赖注入。更重要的是,您将不需要 VC 通用 where 子句。 -
@dvp.petrov
ReadingBookPageDataSource和StarsBookPageDataSource有很多相同的方法,所以我在BookPageDataSource的基础上编写了这些方法。如果我将BookPageDataSource更改为协议,我需要将扩展添加到协议中,所有存储的变量都应该使用objc_associated_objects方法创建。我认为这很糟糕...... -
我同意 dvp.petrov 但你也可以在你的 ViewController 中使用
associatedtype这可能是一个数据源 -
@Sweeper 你能解释一下如何在当前示例中执行此操作吗?
标签: ios swift generics covariance