ios - Swift - 从也是 UIViewController 的通用基类继承 UIViewController

标签 ios swift oop generics inheritance

所以我有一个基类,DataViewController<T> ,继承自 UITableViewController如下:

class DataTableViewController<T : BMPage<BMData>> : UITableViewController, UISearchBarDelegate {
    // implementations...
}

我还有一个TournamentsViewController它继承自 DataViewController传入泛型:

class TournamentsViewController: DataTableViewController<TournamentPage> {
    // overrides, etc.
}

供引用,这里是BMPage<T> :

open class BMPage<T : Codable> : Decodable {

    public enum CodingKeys: String, CodingKey {
        case data
    }

    var data : [T]

    required public init(from decoder:Decoder) throws {
        let vals = try decoder.container(keyedBy: CodingKeys.self)
        data = try vals.decode([T].self, forKey: .data)
    }
}

extension BMPage: Encodable {
    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(data, forKey: .data)
    }
}

...和BMData :

open class BMData : Codable {

    public enum CodingKeys: CodingKey {
        case id
        case name
    }

    var id: Int
    var name: String

    required public init(from decoder:Decoder) throws {
        let vals = try decoder.container(keyedBy: CodingKeys.self)
        id = try vals.decode(Int.self, forKey: .id)
        name = try vals.decode(String.self, forKey: .name)
    }
}

我想要实现的目标:各种UITableViewController只需指定泛型即可指定其特定数据的子类。这是我的 Tournament 和 TournamentPage 实现,它们应该更好地解释这个概念:

open class Tournament : BMData {
    let game_id: Int = 0
    let game_iteration_id: Int = 0
    let state: Int = 0
    let starts_at: String = ""
    let creator_id: Int = 0
    let stream_url: String? = nil
    let entrant_count: Int = 0
    let prereg_count: Int = 0
    let path: String = ""
}

open class TournamentPage : BMPage<BMData> {
    public enum CodingKeys: String, CodingKey {
        case data = "tournaments"
    }

    let page: String? = nil
    let results_per_page: String = ""
    let tournament_count: Int = 0
}

问题:编译器不喜欢我这样做,因为它会抛出多个但非常相似的错误,例如:

  • Cannot convert return expression of type 'TournamentsViewController' to return type 'UIViewController'
  • Cannot convert return expression of type 'TournamentsViewController?' to return type 'UIViewController?'

下面是此类表达式的一个示例(取自 XCode 放入的默认 ModelController,这是所有这些错误发生的地方:

    let dataViewController = storyboard.instantiateViewController(withIdentifier: "DataViewController") as! TournamentsViewController

有办法实现我想要做的事情吗?我承认,我是 Swift 新手(本周才开始学习),所以也许我完全误解了典型的 Swift 实践以及它的设计目的,但可以用 C# 等语言来实现这一点(也可能甚至 Objective-C(虽然我对它有点生疏,因为自从我上次使用它以来已经有一段时间了)也是我在这里所做的。

最佳答案

您是否尝试过像这样实例化 View Controller ?
let viewController = MyTableViewController()navigationController.pushViewController(viewController, animated: true) }

关于ios - Swift - 从也是 UIViewController 的通用基类继承 UIViewController,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53234700/

相关文章:

php - 如何在完整的 OO 应用程序中处理依赖注入(inject)

java - Comparator<T> 如何成为函数式接口(interface)?

matlab - MATLAB OOP 速度慢还是我做错了什么?

ios - 在 NavigationController 中推送多个 UIViewController

ios - Swift:transitionFromView 翻转整个屏幕而不是 View

ios - Swift IOS 应用程序在哪里实例化 View 和 ViewController?

ios - "No such module ' LocalAuthentication '"尝试使用 Swift 在 Xcode 6 中导入时

swift - 如何根据字符在 Swift 中修剪字符串

ios - viewDidAppear 和 viewDidLoad 初始化位置太晚了

ios - 列出照片库中的所有 gif 文件