0

Possible Duplicate:
What happens if two ObjC categories override the same method?

I have two Categories on NSString class as follows:

//first category

#import "NSString+MyCategory1.h"

@implementation NSString (MyCategory1)

-(void)myMethod{
    NSLog(@"this is my method from category 1");
}

@end

//second category

#import "NSString+MyCategory2.h"

@implementation NSString (MyCategory2)

-(void)myMethod{
    NSLog(@"this is my method from category 2");
}

@end

But the following main method is always calling myMethod from MyCategory1 even after import of the same has been commented out.

#import <Foundation/Foundation.h>
//#import "NSString+MyCategory1.h"
#import "NSString+MyCategory2.h"

int main(int argc, const char * argv[])
{

    @autoreleasepool {

        [[[NSString alloc]init] myMethod];

    }
    return 0;
}

Please anyone explain this behavior and how this behavior is useful in practice.

Community
  • 1
  • 1
siva636
  • 16,109
  • 23
  • 97
  • 135

1 Answers1

4

I think what this shows is that you should not have methods in categories that clash.

My (semi informed) guess is that which method gets called us down to how the app was compiled, so it's not something you can influence at runtime. And it's not really useful in practice, it's just... what happens.

As for why this happens, the header file doesn't say what to do when the method is called, only that an implementation for it exists. In your case, it does exist. It just happens not to be the one you want.

Stephen Darlington
  • 51,577
  • 12
  • 107
  • 152
  • 1
    Though I don't really know what's going on in the compiler/linker, the effect seems like a bug to me. My gut reaction is that, if there's no way to distinguish the method names, it should cause a duplicate symbol error at link time rather than an arbitrary choice during execution. – Phillip Mills Nov 08 '12 at 13:28
  • 1
    @PhillipMills No, it's not a bug. This is just how categories work. When a category is loaded it adds the methods it implements or overrides if they already exist. It's on purpose that this happens and there's no duplicate symbol error as they are different symbols since they are in different categories. It's not an arbitrary choice during execution - the final category to be loaded wins. – mattjgalloway Nov 08 '12 at 13:33
  • Thanks for the information...though unless there's a way to control the order of loading (?) I'd still call the effect arbitrary from the developer's point of view. :) – Phillip Mills Nov 08 '12 at 13:37
  • Working as per the design doesn't necessarily mean that the design was good... – Stephen Darlington Nov 08 '12 at 13:57
  • Categories are no replacement for subclassing. If I want a class to react differently to the same message, I have to subclass it and override that message. If we would allow to load several categories with the same methods, it could lead to unmaintainable code. – vikingosegundo Nov 08 '12 at 14:05