是否可以在泛型中包含泛型?
我有这个协议(protocol)
public protocol ListViewModelProtocol {
typealias ViewModel
typealias Cell
func titleForHeaderInSection(section: Int) -> String?
func numberOfSections() -> Int
func numberOfRowsInSection(section: Int) -> Int
func viewModelAtIndexPath(indexPath: NSIndexPath) -> ViewModel
}
我也有基地ListViewModel
实现此协议(protocol)
public class BaseListViewModel<T, U> : ListViewModelProtocol {
}
但这里已经说我的 ListViewModelProtocol
没有实现。如何将 T 和 U 设置为协议(protocol)内的特定类?因为如果我把这个写在协议(protocol)中
typealias ViewModel: CustomClass
typealias Cell: CustomCell
它仍然无法工作。
我的目标是子类 BaseListViewModel
喜欢
public class TestListViewModel : BaseListViewModel<TestCellViewModel, TestTableViewCell> {
}
然后我可以在我的 BaseViewController
中执行此操作
public class BaseViewController<T: ListViewModelProtocol>: UITableViewController {
}
在某些子类中 ViewController
这样做:
public class CustomViewController: BaseViewController<TestListViewModel> {
}
这样CustomViewController
会“得到”TestCellViewModel
和TestTableViewCell
(实际上是它的 BaseViewController)。
但是这当然没有像我预期的那样工作。我缺少什么?或者我必须定义 typealias
对于 ListViewModelProtocol
在每个实现它或将其用作泛型类型的类中?这意味着我必须定义 ViewModel
和Cell
的ListViewModelProtocol
两者皆 BaseListViewModel
类和BaseViewController
类,但这不是那么通用,因为我只想将这些基类型放入协议(protocol)中,仅此而已。
或者我的方法可能有问题,我应该以不同的方式实现它?
任何建议都是有用的。谢谢
编辑
我已经设法解决了这个问题,但我还有另一个问题。
public class BaseViewController<T: ListViewModelProtocol>: UITableViewController {
var dataSource: T?
}
此数据源通过调用其自己的方法在 UITableViewDataSource 方法内使用(请参阅 ListViewModelProtocol 方法)。一切工作正常,但是当一些自定义 Controller 时:
Controller: BaseViewController<TestListViewModel>
正在取消初始化,我收到 EXC_BAD_ACCESS 错误。如果我放
deinit {
self.dataSource = nil
}
它有效,但我想知道为什么我需要将其设置为 nil。
谢谢。
最佳答案
typealias 关键字有多种含义...
// protocol can't be generic
protocol P {
// here typealias is just placeholder, alias
// for some unknown type
typealias A
func foo(a:A)->String
}
// C is generic
class C<T>:P {
// here typealias define the associated type
// in this example it is some generic type
typealias A = T
func foo(a: A) -> String {
return String(a)
}
}
let c1 = C<Int>()
print(c1.foo(1)) // 1
let c2 = C<Double>()
print(c2.foo(1)) // 1.0
// D is not generic!!!
class D: C<Double> {}
let d = D()
print(d.foo(1)) // 1.0
更新,回答讨论中的问题
class Dummy {}
protocol P {
// here typealias is just placeholder, alias
// for some inknown type
typealias A : Dummy
func foo(a:A)->String
}
// C is generic
class C<T where T:Dummy>:P {
// here typealias define the associated type
// in this example it is some generic type
typealias SomeType = T
func foo(a: SomeType) -> String {
return String(a)
}
}
class D:Dummy {}
let c = C<D>()
print(c.foo(D())) // D
和
// now next line doesn't compile
let c1 = C<Int>() // error: 'C' requires that 'Int' inherit from 'Dummy'
关于swift - 通用 Controller 内的通用 Swift 协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34859516/