将UITableViewDataSource放入泛型类时的NSInvalidArgumentException

时间:2014-12-15 11:58:42

标签: uitableview swift

我尝试将我的表数据源封装到一个名为ArrayDataSource的自己的类中,该类看起来像以下几行代码:

public class ArrayDataSource<T>: NSObject, UITableViewDataSource {
    var items: [[T]]

    // ...

    public func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return self.items.count
    }

    public func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.items[section].count
    }

    // ...

}

这非常合适,并且没有关于缺失实现的抱怨,但是当使用它时

self.tableViewDataSource = ArrayDataSource<Stop>(items: stopsInSections, cellReuseIdentifier: "StopCell", configureClosure: { view, stop in /* ... */ })
// yes, self.tableViewDataSource is a strong reference, since self.tableView.dataSource doesn't seem to be
self.tableView.dataSource = self.tableViewDataSource

但是当我使用它时,我的应用程序崩溃了以下调试输出:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_TtC12WannWieWohin15ArrayDataSource00000000146B4108 tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x146b4250'

任何想法我可能做错了吗?

2 个答案:

答案 0 :(得分:2)

从类声明中删除泛型,您的代码将起作用 但这看起来像一个bug(泛型或respondsToSelector:?)。

// with Generics
public class ArrayDataSource<T>: NSObject, UITableViewDataSource { ... }

var ds = ArrayDataSource<String>()
ds.respondsToSelector("tableView:numberOfRowsInSection:") // false

// without Generics
public class ArrayDataSource2: NSObject, UITableViewDataSource { ... }

var ds2 = ArrayDataSource2()
ds2.respondsToSelector("tableView:numberOfRowsInSection:") // true

答案 1 :(得分:0)

不幸的是,你不能在Cocoa中使用通用的swift类 - 动态方法调用失败。

目前您可以采用的一种方法是在您的通用数据源上拥有一个属性,该属性返回一个非泛型类,它包装您的泛型类。

这里有一种实现方法: https://github.com/jonnermut/thesarvo/blob/master/thesarvo_iphone_2.0/thesarvo/thesarvo/Model/SectionedDataSource.swift