0

I have an Objective-C method (declared in the class named "BaseViewModel" of my old framework) that is :

-(void) updateFromManagedObject:(__kindof NSManagedObject *)entity;

I want to use it in mutiple Swift classes. Each Swift class will use a particular subclass of NSManagedObject and inherits from "BaseViewModel". When i try to override this func like this :

override func updateFromManagedObject(entity: Person?) {
    <#code#>
}

OR

override func updateFromManagedObject(entity: Animal?) {
    <#code#>
}

the compiler returns :

Method does not override any method from its superclass

It only works with :

override func updateFromManagedObject(entity: NSManagedObject?) {
    <#code#>
}

How can I use specifics inherited types of NSManagedObject ? (Maybe with a class Generic-Type ? I try but failed too :/ )

QLag
  • 823
  • 1
  • 13
  • 33
  • What you are trying to achieve is function overloading, however this is not possible with Objective-C functions/methods as Objective-C doesn't support overloading. – Cristik Jan 19 '16 at 18:14
  • Perhaps if you post some example of the ViewModel classes maybe we'll find another approach. – Cristik Jan 19 '16 at 18:15
  • @Cristik no need to post anything else, the code I gave is enough to explain the problem. You're right it's `overloading` and not `overriding`but it was working with Obj-C – QLag Jan 20 '16 at 08:28
  • Then my answer is NO, you can't do this kind of overloading with the `objc` method :) – Cristik Jan 20 '16 at 08:36

3 Answers3

4

The point of overriding is that the subclass method is called instead of the superclass method when the receiver is an instance of the subclass. Therefore, the subclass method's parameters must handle at least all the parameters the superclass method can handle. So the subclass method's parameters' types must be the same or more general than the parameters' types for the superclass method it overrides.

newacct
  • 119,665
  • 29
  • 163
  • 224
  • Okay I understand and thx for this answer, but it was working with Obj-C. My method subclass was `-(void) updateFromManagedObject:(Animal *)entity { <#code#> }`, and it was called, so is it a specific Swift restriction ? – QLag Jan 20 '16 at 08:23
  • In fact, I think that Obj-C methods call was only based on performing selectors. And selectors don't take into account the parameters type, so It was working. Swift is more strict and forbid this practice. – QLag Jan 20 '16 at 08:41
0

You cannot overload Objective-C functions based on the argument type, as Objective-C doesn't support this kind of overloading. This is why only the NSManagedObject overriding works.

If you want different behaviour based on the entity type, an alternative would be to declare a Swift-only method:

func updateFromManagedObject2(animal: Animal) {
}

func updateFromManagedObject2(person: Person) {
}
Cristik
  • 30,989
  • 25
  • 91
  • 127
0

You can't override that method because types in objective-c and swift are a bit different. the types have to line up exactly, or overriding won't work.

Both statements So the subclass method's parameters' types must be the same or more general than the parameters' types for the superclass method it overrides. and You cannot overload Objective-C functions based on the argument type, as Objective-C doesn't support this kind of overloading above are correct.

Another example of overriding illustrating this:

- (UIColor*)getDataPointColor:(int)index
{
    return UIColor.whiteColor;
}
override func getDataPointColor(_ index: Int32) -> UIColor {
   return UIColor.redColor
}

Note that override func getDataPointColor(_ index: Int) -> UIColor { won't work. (Not sure why, 64-bit code and all...)

spnkr
  • 952
  • 9
  • 18