Different behavior between T.Type & [T.Type]

76 Views Asked by At

I am using generics func to improve tableView cells as below;

public func registerNib<T: UITableViewCell>(_:T.Type) {
    print("Registering.....")
    print(T.self)
    let nib = UINib(nibName: String(describing: T.self), bundle: nil)
    register(nib, forCellReuseIdentifier: String(describing: T.self))
}

And I wrote two func to register cell, one for single cell and one for multiple cells.

//Single Cell Register

func setup<T: UITableViewCell>(cell:T.Type) {
   print(cell)
   tableView.registerNib(cell)
   self.setupParameters(.....)
}

//Multiple Cell Register

func setup<T: UITableViewCell>(cells:[T.Type]) {
   for cell in cells {
        print(cell)
        tableView.registerNib(cell)
    }
   self.setupParameters(.....)
}

For single cell implementation, you can call func as below and it will registerNib correctly.

self.baseTableView.setup(cell: CompetencyCell.self, rowHeight: 60)

**************
Output:
CompetencyCell
Registering...
CompetencyCell

But problem is occur with multiple implementation;

self.baseTableView.setup(cells: [CompetencyCell.self, BehaviorCell.self], rowHeight: 60)

**************
Output:
CompetencyCell
BehaviorCell
Registering...
UITableViewCell
UITableViewCell

I really wonder what is the reason, or what I miss? It looks like same behavior but when I want to pass T.Type value to RegisterNib method it turns to UITableViewCell and after some point of course I got crash because it could not find the cell.

Do you have any advice? Thanks a lot.

2

There are 2 best solutions below

1
On

When calling a generic function the generic type T represents a single static type.

[T.Type] is nonsensical because it declares an array of the same type specifier.

T doesn't mean Any!

2
On

As described in vadian's answer, generic is not a good tool to use with Array containing multiple types of values.

You can try something like this:

extension UITableView {
    public func registerNib(_ type: UITableViewCell.Type) {
        print("Registering.....")
        print(type)
        let nib = UINib(nibName: String(describing: type), bundle: nil)
        register(nib, forCellReuseIdentifier: String(describing: type))
    }
}

And this:

func setup(cells: [UITableViewCell.Type] /*, otherParams: ...*/) {
    for cell in cells {
        print(cell)
        tableView.registerNib(cell)
    }
    //self.setupParameters(.....)
}