Call precedence for method overridden in category and again in subclass
Asked Answered
S

2

5

I'm working on a project in Objective-C and I'm facing a situation.

Let's say I have a class named Foo. I implement a category for this class named Foo+Bar and override Foo's method fooMethod:.

Then I create a subclass for Foo, named Baz and override the same fooMethod: in this class.

  1. When I use the method fooMethod: on a Baz object, which implementation will be called? The one inside the Foo+Bar or the one inside Baz?
  2. How does Objective-C handle this situation and why?

I'm open to any good explanation and/or documentation.

Spindlelegs answered 30/7, 2015 at 7:50 Comment(1)
regarding the 'how' just put a log in each of these methods and watch for the results (I believe the subclass method will be called in this case)Chemist
C
6

Behaviour if you override a method in a category is explicitly undefined. So please don't:

If the name of a method declared in a category is the same as a method in the original class, or a method in another category on the same class (or even a superclass), the behavior is undefined as to which method implementation is used at runtime.

If you were overriding a method defined once in a category of the superclass then of course the subclass implementation would be called.

But here you override a method defined twice in the superclass. Behaviour is likely to be undefined, because you override an undefined implementation. Even if this worked, it would be bad code anyway.

Really, please don't do this.

Christiechristin answered 30/7, 2015 at 8:4 Comment(6)
Interesting. Do you have a reference for this?Kimberleekimberley
Can a method defined in a category be overriden in a subclass of the same class? I would love to read an official documentation on this if you know any.Spindlelegs
@Kimberleekimberley Updated answer.Christiechristin
@Spindlelegs Most of Cocoa's methods are implemented in categories. So if you couldn't override in a subclass the methods defined in a category of the superclass, then you would have trouble sub classing most of Cocoa's classes.Christiechristin
@Christiechristin there seems to be a problem with the Apple Developer link you provided. It says that the page could not be found.Spindlelegs
My first answer was right, but when I searched for references I found some obsolete documentation that said it was allowed in special cases. Current documentation explicitly says it's undefined so I reverted to my previous answer, with a reference this time :)Christiechristin
M
1

Did simple testing of your example, which showed that category's implementation is called on instance of Buz class even if I did not include header Foo+Bar anywhere, I used iPhone 6 simulator with iOS 8.1. Apple says that behaviour is unpredictable, so it is bad practice to do such coding.

If the name of a method declared in a category is the same as a method in the original class, or a method in another category on the same class (or even a superclass), the behavior is undefined as to which method implementation is used at runtime.

see, https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html Section Avoid Category Method Name Clashes

Montane answered 30/7, 2015 at 8:23 Comment(3)
Can you share the link where Apple says this?Spindlelegs
Unfortunately, testing something which is documented as UB strictly speaking only tells you what happened in your specific case -- compiler/runtime/time of day/color of hair -- not what will happen for other circumstances.Territerrible
@JoshCaswell Yep, did not I write the same conclusion? Even showed the documentation. Testing was just for fun.Montane

© 2022 - 2024 — McMap. All rights reserved.