Reputation: 12085
I tried to encapsluate my tables data source into an own class called ArrayDataSource
which looks like the following lines of code:
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
}
// ...
}
This complies quite fine and no complaints about missing implementations are made, but when using it like
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
But when I use it, my app crashes with the following debug output:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_TtC12WannWieWohin15ArrayDataSource00000000146B4108 tableView:numberOfRowsInSection:]: unrecognized selector sent to instance 0x146b4250'
Any ideas what I could have made wrong?
Upvotes: 0
Views: 127
Reputation: 1489
Unfortunately you can't use a generic swift class with Cocoa - the dynamic method calls fail.
One approach you can do at the moment is have a property on your generic datasource that returns a non-generic class that wraps your generic one.
There is an implementation of this approach here: https://github.com/jonnermut/thesarvo/blob/master/thesarvo_iphone_2.0/thesarvo/thesarvo/Model/SectionedDataSource.swift
Upvotes: 0
Reputation: 2459
Removing generics from class declaration, your code will work.
But this looks like a bug(of generics or 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
Upvotes: 2