views:

403

answers:

3

I am extending a class from a external library. Here is my code:

Header file: Manager+MyCategory.h

#import "Manager.h"
#import "Element.h"

@interface Manager (myCategory) 
- (Element*) elementWithTag:(NSInteger)tag; 
@end

Implementation file: Manager+MyCategory.h file

@implementation Manager (myCategory) 

- (Element*) elementWithTag:(NSInteger)tag {
    ...
}

@end

Now here is how I use this category:

#import "Manager+MyCategory.h"

@implementation myClass 

- (void) myFunction:(NSInteger)tag {
   Manager* myManager = [[Manager alloc] init];
   Element* = [myManager elementWithTag:tag];

   ...

   [myManager release];
}

@end

When I compile I have no warnings but when I run my program I get the following error:

*** -[Manager elementWithTag:]: unrecognized selector sent to instance 0x105d9a0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[Manager elementWithTag:]:

Header file (ie Manager+MyCategory.h) is correctly imported but it looks like the link with the implementation file is not done. If I replace #import "Manager+MyCategory**.h**" by #import "Manager+MyCategory**.m**" in my class it's working properly.

Anyone can explain me what I forgot? Thanks

+1  A: 

I suspect that you have forgotten to add the Manager+MyCategory.m to the approrpriate target in Xcode. You do not get a linker error because all the symbols exist and there is no compiler warning because you have included the appropriate header files, but at runtime the implementation of the elementWithTag: method is missing.

Barry Wark
Good point! but I checked and Manager+MyCategory.m is well in the target compile sources. Thx anyway
Thomas
Another sanity check never hurt. Try throwing a #error in your Manager+MyCategory.m. If the compiler doesn't fail, you know for sure your category isn't getting compiled.
kperryua
Sorry I couldn't be of help. I'll leave the answer here because it may help someone else in the future. Good luck.
Barry Wark
@kperryua Tried throwing an exception in Manager+MyCategory.m and nothing happened. My category is definitely not compiled. Now let's find why. Thanks for your help
Thomas
This was my problem, and including the .m file fixed the error. Didn't think to look there though...
casademora
A: 

Apologies, could not add this as a comment...

Just for testing, you may want to add an extern c function declared in the header and implemented in the .m file. If you call this c function within your test code then this will generate a linker error due to an unresolved identifier.

This can make it easier to investigate the problem as it provides immediate feedback and may generate some additional clues as to why the file is not being included.

Given the time frame, I'll assume you've done this, but just in case... make sure that you've cleaned the target, shut down XCode, and then re-open. I've had the project files become corrupted in memory and act strangely.

Barney

Barney Mattox
Ooooh!! Something interesting happened (even though I don't think the work "interesting" is approriate :) ).I added an extern c function in my category header and implemented in the .m file. I called it within my test code and, guess what, everything works properly: external function is called as well as the "elementWithTag" method.I don't understand anything and going nuts.Of course I cleaned the target, close and re-open XCode.ThanksThomas
Thomas
I forgot to mention that if I remove the extern C function it's not working anymore.
Thomas
That is quite interesting. Have you tried adjusting the linker settings, such as disabling "Dead Code Stripping". I suspect this is some sort of flaw in the linker optimization. It would be a good idea to open a bug report with Apple.
Barney Mattox
+1  A: 

Categories do not work well with traditional Unix static libraries.

If that's your case, it seems that passing the -ObjC option to the linker resolves the issue.

Apple Technical Q&A QA1490 explains it all.

IlDan
Thanks! Just add -ObjC linker flag to my project and it works properly
Thomas