1

Ok here's the problem:

say we have a parent class that holds an array of ChildClasses

class ParentClass {

    var list: [ChildClass<UITableViewCell>] = []

    func append<T>(cell: T) where T: UITableViewCell {
        let child = ChildClass<T>()
        list.append(child)
    }

}

and the child class

class ChildClass<T> where T: UITableViewCell {

    var obj: T!

}

both of the classes are generic and the Type(T) is alway of the type UITableViewCell

now if you try to build it you'll get this error:

Cannot convert value of type ChildClass< T > to expected argument type ChildClass< UITableViewCell >

but if the T is a subclass of UITableViewCell, shouldn't it be able to convert the T???
thanks in advance

Alexander
  • 59,041
  • 12
  • 98
  • 151
Mohsen Shakiba
  • 1,762
  • 3
  • 22
  • 41
  • Strongly related (dupe?): [How do I store a value of type Class in a Dictionary of type \[String:Class\] in Swift?](http://stackoverflow.com/q/38590548/2976878) – Hamish Mar 06 '17 at 07:54
  • it's really hard to find that question, still if you think it's duplicate, i agree – Mohsen Shakiba Mar 06 '17 at 07:58

2 Answers2

1

ChildClass<T> is not a subclass of ChildClass<UITableViewCell>, even if T is a subclass of UITableViewCell.

My answer here provides an example of what can go wrong if such a covariance was established: https://stackoverflow.com/a/42615736/3141234

Community
  • 1
  • 1
Alexander
  • 59,041
  • 12
  • 98
  • 151
  • Ok, but how can I store items with different type of the same subclass in a list with generics?? – Mohsen Shakiba Mar 06 '17 at 07:38
  • You have to define child as `ChildClass()`, and assign `cell` to its `obj`. Note of course, that this upcasts the `cell` to be `UITableViewCell`, losing type information. – Alexander Mar 06 '17 at 07:41
  • so I will lose the type information and I have to add additional cast for it to work. well guess you are right, thanks anyway – Mohsen Shakiba Mar 06 '17 at 07:42
  • @MohsenShakiba Yup, there's no way around that. As Sweeper pointed out, `ChildClass` is a completely unrelated type to ChildClass` – Alexander Mar 06 '17 at 07:44
  • I've voted up both, but which one of the answers do you think deserves the mark?? – Mohsen Shakiba Mar 06 '17 at 07:58
1

Swift is very strict with generics. ChildClass<UITableViewCell> is not compatible with ChildClass<SomeSubclassOfUITableViewCell>.

One workaround for this is to convert the ChildClass<SomeSubclassOfUITableViewCell> to ChildClass<UITableViewCell>, since logically, they should be compatible. I also noticed that you have not used the cell parameter, so maybe this is how you want your method to be:

func append<T>(cell: T) where T: UITableViewCell {
    let child = ChildClass<UITableViewCell>()
    child.obj = cell
    list.append(child)
}
Sweeper
  • 213,210
  • 22
  • 193
  • 313