Objective-c – What happens if two ObjC categories override the same method

categoriescocoainheritancemethodsobjective c

I know of a couple of rules regarding Objective-C categories:

  1. Category methods should not override existing methods (class or instance)
  2. Two different categories implementing the same method for the same class will result in undefined behavior

I would like to know what happens when I override one of my own category methods in the same category. For example:

@interface NSView (MyExtensions)
- (void)foo; // NSView category implementation
@end

@interface MyClass : NSView
{ }
@end

@interface MyClass (MyExtensions)
- (void)foo; // MyClass category implementation
@end

With these interfaces defined, which method will be executed when I run the following code?

MyClass * instance = [[MyClass alloc] initWith...];
[instance foo];
[instance release];

Note: With my compiler, the MyClass implementation takes precedence, but I'm not sure if that is guaranteed to occur, or simply one specific flavor of undefined behavior.

Best Answer

To extend on drawnonward answer:

It's matter of hierarchy. Categories are really just a means of organizing source files. When compiled, all the methods of a class, including the ones defined in any category, end up in the same file.

Anything you could do in a regular class interface you can do in a category and anything you shouldn't do in a regular class interface you shouldn't do in a category.

So:

Category methods should not override existing methods (class or instance)

You can use methods defined in the regular class interface to override inherited methods so you can override inherited methods in a category.

However, you would never try to have to two identical method definitions in the same ordinary interface so you should never have a method in a category that has the same name as a method in either the ordinary interface or another category on the same class. Since all the method definitions end up in the same compiled file, they would obviously collide.

Two different categories implementing the same method results in undefined behavior

That should be rewritten to say "Two different categories implementing the same method for the same class results in undefined behavior." Again, because all the methods for any one class end up in the same file, having two methods in the same class would obviously cause weirdness.

You can use categories to provide methods that override superclass methods because a class and its superclass are two distinct classes.

If your ever confused about whether a category will cause problem just ask yourself this: "Would the methods in the category work if I copied and pasted them all into the class' .h/.m files?" If the answer is "yes" then you're in the clear. If "no", then you've got problems.