Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declarations from extensions cannot be overridden yet in Swift 4

I have recently migrated my code to Swift 4. There is an issue that I am facing with extensions, i.e.:

Declarations from extensions cannot be overridden yet

I have already read multiple posts regrading this issue. But none of them entertains the scenario described below:

class BaseCell: UITableViewCell
{
    //Some code here...
}

extension BaseCell
{
    func isValid() -> String?
    {
        //Some code here...
    }
}

class SampleCell: BaseCell
{
    //Some code here...

    override func isValid() -> String? //ERROR..!!!
    {
        //Some code here...
    }
}

According to Apple,

Extensions can add new functionality to a type, but they cannot override existing functionality.

But in the above scenario, I am not overriding the method isValid() in extension. It is overridden in the SampleCell class definition itself. Still, it is giving the error.

like image 481
PGDev Avatar asked Oct 04 '17 12:10

PGDev


4 Answers

But in the above scenario, I am not overriding the method isValid() in an extension.

isValid gets declared in an extension.

The error pretty much says that if a function is declared this way, it cannot be overridden.

The statement is valid for both from an extension and in an extension.

like image 133
Tamás Sengel Avatar answered Nov 01 '22 03:11

Tamás Sengel


You can override declarations from extensions as long as you @objc the protocol. In Swift 4.2:

class BaseClass {}
class SubclassOfBaseClass: BaseClass {}

@objc protocol IsValidable {
    func isValid() -> Bool
}

extension BaseClass: IsValidable {
    func isValid() -> Bool { return false }
}

extension SubclassOfBaseClass {
    override func isValid() -> Bool { return !super.isValid() }
}

BaseClass().isValid()           // -> false
SubclassOfBaseClass().isValid() // -> true
like image 26
Adam Preble Avatar answered Nov 01 '22 02:11

Adam Preble


In Swift 3, you were able to override the function of extension if extension was of a class that is getting derived from Objective-C (http://blog.flaviocaetano.com/post/this-is-how-to-override-extension-methods/), but I guess its not possible now in Swift 4. You can ofcourse do something like this:

protocol Validity {
    func isValid() -> String?
}

class BaseCell: UITableViewCell, Validity {

}

extension Validity
{
    func isValid() -> String? {
        return "false"
    }
}

class SampleCell: BaseCell {

    func isValid() -> String? {
        return "true"
    }
}


let base = BaseCell()
base.isValid() // prints false

let sample = SampleCell()
sample.isValid() // prints true
like image 5
Puneet Sharma Avatar answered Nov 01 '22 01:11

Puneet Sharma


I think this is self-explanatory. declarations FROM extensions cannot be overridden yet

You are trying to override the function func isValid() -> String? which was declared within an extension of BaseCell, not the BaseCell class itself.

It is clearly saying that you can't override something that was declared inside an extension.

Hope it is helpful.

like image 3
Tarun Tyagi Avatar answered Nov 01 '22 01:11

Tarun Tyagi