Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make an extensions of generic class in Swift4

Lets assume we have a simple generic class:

class Foo<T> {

}

next add to this class an extension which implements UITableViewDatasoure:

extension Foo: UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        //Code here
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //Code here
    }
}

This construction causes a compiler error with message:

@objc is not supported within extensions of generic classes or classes that inherit from generic classes Non-'@objc' method

'tableView(_:numberOfRowsInSection:)' does not satisfy requirement of '@objc' protocol 'UITableViewDataSource'

Anyone can tell me why? And how to fix that?

like image 600
Kamil Harasimowicz Avatar asked Jan 22 '18 16:01

Kamil Harasimowicz


People also ask

What is generic in IOS?

Apple doc says: Generic code enables you to write flexible, reusable functions and types that can work with any type. You can write code that avoids duplication by using generics in most cases.

What is T type Swift?

The placeholder type T is used in the function declaration. It tells Swift that this function can find any item in any array, as long as the foundItem and items in the array are of the same type. This makes sense — you want to look for a T value in an array of T values.


2 Answers

The error message seems very clear. This isn't supported. You can't attach an @objc method to a generic class in an extension. You need to define these methods in the class definition, not an extension. The "why" is "the compiler doesn't support it today." (It's likely hard to support because of specializations, but the real answer is "the compiler can't do it.")

like image 109
Rob Napier Avatar answered Sep 26 '22 12:09

Rob Napier


Currently the Xcode doesn't support attach an @objc method to a generic class in an extension, you can fix it by define the method inside the class definition, as following:

class Foo<T>: UIViewController, UITableViewDataSource {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        //Code here ...
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //Code here ...
    }
}
like image 34
HanleyLee Avatar answered Sep 26 '22 12:09

HanleyLee