Swift:对泛型类的引用

Swift:对泛型类的引用,swift,generics,Swift,Generics,这是密码 protocol TestType : AnyObject { } class Generic<TestType> : NSObject { private let filterFunction : (TestType,String) -> Bool init(filter: @escaping (TestType,String) -> Bool) { filterFunction = filter } } cl

这是密码

protocol TestType : AnyObject {

}

class Generic<TestType> : NSObject {

    private let filterFunction : (TestType,String) -> Bool

    init(filter: @escaping (TestType,String) -> Bool) {
        filterFunction = filter
    }
}

class Parent : UIViewController {
    public var generic : Generic<TestType>!
}

class Child : Parent {

    override func viewDidLoad() {
        // ERROR THIS LINE
        generic = Generic<Object>(filter: { (str1, str2) -> Bool in
            return true
        })
    }
}

class Object : TestType {

}
协议测试类型:AnyObject{
}
类泛型:NSObject{
私有let过滤器函数:(TestType,String)->Bool
init(过滤器:@escaping(TestType,String)->Bool){
过滤器功能=过滤器
}
}
类父级:UIViewController{
公共变量通用:通用!
}
类子:父{
重写func viewDidLoad(){
//这行出错
generic=generic(过滤器:{(str1,str2)->Bool-in
返回真值
})
}
}
类对象:TestType{
}
错误是:

Cannot assign value of type 'Generic<Object>' to type 'Generic<TestType>!'
无法将“Generic”类型的值赋值给“Generic!”
我尝试了很多方法,比如typealias,但无法编译代码。 问题是我不想要
父类
子类
类,因为我希望能够在IB中使用它


如何在父级中存储泛型引用,并在子级中初始化它(动态地,通过设置具体的TestType-like对象或其他对象)

我终于成功地完成了我想要的

一点也不完美,请随意评论架构改进(特别是在asBaseProtocol()部分…)

这是我的完整代码(Swift 3.0

数据过滤器

protocol DataFilterDelegate : class {
    func didFilter()
    func didUpdateItems()
}

class DataFilter<T> {
    public weak var delegate : DataFilterDelegate?

    private var items : [SelectableItem<T>]?
    private var filteredItems : [SelectableItem<T>]?
    var source: [SelectableItem<T>]? {
        get {
            if filteredItems != nil {
                return filteredItems
            }
            return items
        }
    }

    var filter : (T,String) -> Bool
    var populateCell : (T) -> UITableViewCell

    init(filter : @escaping (T,String) -> Bool, populateCell: @escaping (T) -> UITableViewCell) {
        self.filter = filter
        self.populateCell = populateCell
    }

    func updateItems(_ items: [T]) {
        self.items = [SelectableItem<T>]()
        for item in items {
            self.items?.append(SelectableItem(item))
        }
        delegate?.didUpdateItems()
    }

    func filterItems(text : String) {
        filteredItems = (text == "") ? nil : items?.filter { item in
            filter(item.item, text)
        }
        delegate?.didFilter()
    }

    func selectedItems() -> [T]? {
        guard let items = items else {
            return nil
        }
        var selectedItems = [T]()
        for item in items {
            if item.isSelected {
                selectedItems.append(item.item)
            }
        }
        return selectedItems
    }
}

extension DataFilter where T : FIRDataObject {
    func asBaseProtocol() -> DataFilter<FIRDataObject> {
        return DataFilter<FIRDataObject>(filter: filterAsBaseProtocol(), populateCell: populateCellAsBaseProtocol())
    }

    private func filterAsBaseProtocol() -> ((FIRDataObject,String) -> Bool) {
        return { (object, text) -> Bool in
            self.filter(object as! T, text)
        }
    }

    private func populateCellAsBaseProtocol() -> ((FIRDataObject) -> UITableViewCell) {
        return { (object) -> UITableViewCell in
            self.populateCell(object as! T)
        }
    }
}
协议DataFilterDelegate:类{
func didFilter()
func didUpdateItems()
}
类数据过滤器{
公共弱var委托:DataFilterDelegate?
私有变量项:[SelectableItem]?
私有变量filteredItems:[SelectableItem]?
变量来源:[SelectableItem]{
得到{
如果filteredItems!=nil{
返回过滤器数据项
}
退货项目
}
}
变量过滤器:(T,字符串)->Bool
变量populateCell:(T)->UITableViewCell
初始化(筛选器:@escaping(T,String)->Bool,populateCell:@escaping(T)->UITableViewCell){
self.filter=过滤器
self.populateCell=populateCell
}
func updateItems(u项:[T]){
self.items=[SelectableItem]()
对于项目中的项目{
self.items?.append(可选择项(item))
}
委托?.didUpdateItems()
}
func filterItems(文本:字符串){
filteredItems=(text=“”)?nil:items?.filter{item in
过滤器(item.item,文本)
}
委托?.didFilter()
}
func selectedItems()->[T]{
守卫让项目=其他项目{
归零
}
var selectedItems=[T]()
对于项目中的项目{
如果选择了第1项{
选择editems.append(item.item)
}
}
返回selectedItems
}
}
扩展数据过滤器,其中T:FIRDataObject{
func asBaseProtocol()->DataFilter{
返回数据筛选器(筛选器:filterAsBaseProtocol(),populateCell:populateCellAsBaseProtocol())
}
private func filterAsBaseProtocol()->((FIRDataObject,String)->Bool){
返回{(对象,文本)->Bool-in
self.filter(对象为!T,文本)
}
}
private func populateCellAsBaseProtocol()->((FIRDataObject)->UITableViewCell){
返回中的{(对象)->UITableViewCell
self.populateCell(对象为!T)
}
}
}
ParentViewController类

class ParentViewController : UIViewController {
    public var dataFilter : DataFilter<FIRDataObject>? {
        didSet {
            dataFilter!.delegate = self
        }
    }

    // Some Functions using dataFilter
}
class ChildViewController : Parent {

    // Stored as a variable to not have to cast objects to the good type everytime I access dataFilter
    private var patientDataFilter = DataFilter<Patient>(filter: { patient, text in
        patient.firstname.contains(text) ||
            patient.lastname.contains(text)
    }
        , populateCell: { patient in
            let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "Patient")
            cell.textLabel?.text = patient.lastname + " " + patient.firstname
            cell.detailTextLabel?.text = patient.postalCode + " " + patient.city
            return cell
    })

    override func viewDidLoad() {
        super.viewDidLoad()

        dataFilter = patientDataFilter.asBaseProtocol()
    }

    func someFunc() {
        let patient1 = patientDataFilter.source[0].item
        // OR
        let patient2 = dataFilter.source[0].item as! Patient
    }
}
类ParentViewController:UIViewController{
公共变量数据过滤器:数据过滤器{
迪塞特{
dataFilter!.delegate=self
}
}
//使用数据过滤器的一些函数
}
ChildViewController类

class ParentViewController : UIViewController {
    public var dataFilter : DataFilter<FIRDataObject>? {
        didSet {
            dataFilter!.delegate = self
        }
    }

    // Some Functions using dataFilter
}
class ChildViewController : Parent {

    // Stored as a variable to not have to cast objects to the good type everytime I access dataFilter
    private var patientDataFilter = DataFilter<Patient>(filter: { patient, text in
        patient.firstname.contains(text) ||
            patient.lastname.contains(text)
    }
        , populateCell: { patient in
            let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "Patient")
            cell.textLabel?.text = patient.lastname + " " + patient.firstname
            cell.detailTextLabel?.text = patient.postalCode + " " + patient.city
            return cell
    })

    override func viewDidLoad() {
        super.viewDidLoad()

        dataFilter = patientDataFilter.asBaseProtocol()
    }

    func someFunc() {
        let patient1 = patientDataFilter.source[0].item
        // OR
        let patient2 = dataFilter.source[0].item as! Patient
    }
}
class ChildViewController:父级{
//存储为变量,不必每次访问dataFilter时都将对象强制转换为良好类型
private var patientDataFilter=DataFilter(过滤器:{patient,文本输入
patient.firstname.contains(文本)||
patient.lastname.contains(文本)
}
,populateCell:{患者在
let cell=UITableViewCell(样式:。副标题,重用标识符:“患者”)
cell.textlab?.text=patient.lastname+“”+patient.firstname
cell.detailTextLabel?.text=patient.postalCode+“”+patient.city
返回单元
})
重写func viewDidLoad(){
super.viewDidLoad()
dataFilter=patientDataFilter.asBaseProtocol()
}
func someFunc(){
让patient1=patientDataFilter.source[0]。项
//或
让patient2=dataFilter.source[0]。项目为!Patient
}
}

Compare&–a
Generic
不能转换为
Generic
。为什么不创建一个
Generic
实例呢?Thx@Hamish,你的帖子非常有用。在我的代码中,父类是一个扩展的TableviewController,具有一些搜索功能。我希望我的子控制器继承这些功能,只需根据这些项目向父视图控制器提供一个项目和过滤器列表,就可以正常工作。好的,但我的问题是为什么不在
子视图中创建一个
泛型
?假设您的筛选函数应该对非
Object
类型的参数进行折扣,那么您总是可以添加一个
guard let Object=str1 as?对象else{return false}
到谓词。如果您能告诉我们您实际使用的
Generic
的目的,这会有所帮助。