WKL WKL - 6 months ago 59
Swift Question

Cannot override method with a custom class return type

Is there any method i can use to override a method which returns custom class? When i tried to override any method with a custom class as a return type, Xcode throws me an error

Below are my codes:

class CustomClass {
var name = "myName"
}

class Parent: UIViewController {

override func viewDidLoad() {
methodWithNoReturn()
print(methodWithStringAsReturn())
methodWithCustomClassAsReturn()
}

}

extension Parent {

func methodWithNoReturn() { }
func methodWithStringAsReturn() -> String { return "Parent methodWithReturn" }
func methodWithCustomClassAsReturn() -> CustomClass {
return CustomClass()
}

}


class Child: Parent {

override func methodWithNoReturn() {
print("Can override")
}

override func methodWithStringAsReturn() -> String {
print("Cannot override")
return "Child methodWithReturn"
}

override func methodWithCustomClassAsReturn() -> CustomClass {
return CustomClass()
}

}


The error is when overriding this method:


func methodWithCustomClassAsReturn() -> CustomClass


with error message:


Declarations from extensions cannot be overridden yet

Answer

No reason other than the compiler doesn't support it yet. To override a method defined in an extension to the superclass, you must declare it ObjC-compatible:

extension Parent {
    func methodWithNoReturn() { }
    func methodWithStringAsReturn() -> String { return "Parent methodWithReturn" }

    @objc func methodWithCustomClassAsReturn() -> CustomClass {
        return CustomClass()
    }   
}

// This means you must also expose CustomClass to ObjC by making it inherit from NSObject
class CustomClass: NSObject { ... }

The alternative, without involving all the ObjC snafus is to define these methods in the Parent class (not inside an extension):

class Parent: UIViewController {

  override func viewDidLoad() {
    methodWithNoReturn()
    print(methodWithStringAsReturn())
    methodWithCustomClassAsReturn()
  }

  func methodWithNoReturn() { }
  func methodWithStringAsReturn() -> String { return "Parent methodWithReturn" }
  func methodWithCustomClassAsReturn() -> CustomClass {
    return CustomClass()
  }

}