【问题标题】:Swift - Inheriting UIViewController from a generic base class that is also a UIViewControllerSwift - 从也是 UIViewController 的通用基类继承 UIViewController
【发布时间】:2019-04-13 13:16:18
【问题描述】:

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

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

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

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

供参考,这里是BMPage&lt;T&gt;

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,虽然我对它有点生疏,因为我上次使用它已经有一段时间了)这几乎就是我在这里所做的。

【问题讨论】:

    标签: ios swift oop generics inheritance


    【解决方案1】:

    你试过这样实例化视图控制器吗?
    let viewController = MyTableViewController()navigationController.pushViewController(viewController, animated: true) }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多