views:

39

answers:

2
@interface MySuperclass : NSObject {

}

@end

@interface MySuperclass (MyCategory)

- (void)myMethod;

@end

@interface MySubclass : MySuperclass {

}

@end

@interface MySubclass (MyOtherCategory)

- (void)myMethod;

@end

Is it defined which implementation of -myMethod will be called?

Kochan states in Programming in Objective-C that:

If more than one category declares a method with the same name for the same class, it is not defined which method will be executed when invoked.

But I am not sure whether or not a category on a superclass is considered to be a category on the same class in this context.

+1  A: 

My gut says you'll be fine, but the only way to know is to try. I believe the uncertainty is only within the same class, not the super/subclass relationship.

Joshua Weinberg
The thing about undefined behavior, is that, well, it's *undefined*.If it is undefined behavior and I were to try it and it worked in OS X 10.5/10.6, there's no guarantee they wont change it in 10.7.This is behavior that would be somewhat useful to me if it was explicitly defined to behave the way we both suspect it does, but something I can do without if it could cause me or somebody else headaches down the road.Also at this point there's a fair amount of curiosity involved as well.
Lawrence Johnston
This specific behavior ISN'T undefined though. If it was you wouldn't be able to override methods within system base classes though. I'm pretty sure the category load order is only undefined WITHIN the class, not its subclasses. All categories for the superclass should have loaded before yours does.
Joshua Weinberg
That makes sense. What I was attempting to explain was that I personally was unsure whether it was undefined or not, and what I was looking for was conclusive proof that your (and my) gut instinct was in fact correct. While not conclusive, @Felixyz's and your point about system base classes is at least a very strong indication.
Lawrence Johnston
+2  A: 

Although I can't find a reference, I think it's clear that the implementation in MySubclass (MyOtherCategory) takes precedence. The category's methods are added to that particular class, so the "MyOtherCategory" implementation will belong to your subclass, and it will be looked up before going on to the superclass during message dispatch.

As pointed out in the Objective-C manual, a lot of methods in Cocoa are placed in categories. If the order of look-up wasn't well defined, you couldn't override any of those methods in categories on subclasses, which would make categories almost useless.

Felixyz
This is correct. Categories *only* impact the class they are defined against.
bbum