Reputation: 412
Researching about this topic I found following code:
protocol ReusableView {
static var reuseIdentifier: String { get }
}
extension ReusableView {
static var reuseIdentifier: String {
return String(describing: self)
}
}
extension UITableViewCell: ReusableView {}
extension UITableView {
func dequeueReusableCell<T: UITableViewCell>(for indexPath: IndexPath) -> T {
guard let cell = dequeueReusableCell(withIdentifier: T.reuseIdentifier, for: indexPath) as? T else {
fatalError("Unable to Dequeue Reusable Table View Cell")
}
return cell
}
}
My problem is, despite all of the prototype cells defined within storyboard have unique ReuseIdentifiers, the T.reuseIdentifier is always the same: UITableViewCell.
Even when I define following code
class c1 : UITableViewCell {}
class c2 : UITableViewCell {}
class c3 : UITableViewCell {}
and assign c1,c2,c3 to three prototype cells, the return value still will be UITableViewCell. So the shown example seems a good way to generalize the topic but something is missing.
This my code calling for calling the dequeue method:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(for: indexPath)
// Configure the cell...
let place = places[indexPath.row]
cell.textLabel?.text = place.name
cell.detailTextLabel?.text = "\(place.timestamp)"
return cell
}
Upvotes: 2
Views: 71
Reputation: 274565
You need to specify what kind of table view cell you want when you call the method:
let cell: c1 = dequeueReusableCell(for: indexPath)
This is also mentioned in the later parts of the linked tutorial:
Remember that we leverage generics and type inference. We want to dequeue a
WeatherDayTableViewCell
instance, not aUITableViewCell
instance. But how should the compiler know that we want to dequeue aWeatherDayTableViewCell
instance? The compiler tries to infer the type of the cell constant we define intableView(_:cellForRowAt:)
. It sees that wereturn cell
fromtableView(_:cellForRowAt:)
and, by inspecting the method definition, it infers that cell should be of typeUITableViewCell
. The compiler is correct. The solution is very simple. When we declare the cell constant, we need to explicitly specify its type. The compiler then understands that thedequeueReusableCell(for:
) method should return aWeatherDayTableViewCell
instance.
Also, I think using String(describing: self)
is a bad way of getting the class name. If self
implements CustomStringConvertible
and has a custom description
property, this could break your code. A better way is to use:
return String(describing: Self.self)
Upvotes: 2