Objective C: class category not recognized when compiled in a static library

I have a class category declared and compiled in a mac os static lib:

#import <Foundation/Foundation.h>

@interface NSNumber(MyExtension)
-(NSString *)CallMe;
@end

then this staticLib is added to a mac console app in XCode and used:

#import <Foundation/Foundation.h>
#import "MacStaticLib.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSNumber *one = [NSNumber numberWithInt:12];
        NSLog(@"%@",[one CallMe]);        
    }
    return 0;
}

Compiles fine but fails in runtime, unrecognized selector 'CallMe' send to instance... what's wrong or what I missed?

Thanks!!

Replies

Is the header file with the extension public and included in the framework umbrella header?

Yes, the extension is public and in the header file, I'm sorry, I don't know what's the framework umbrella header. Another thing I noticed now is if I add -ObjC on 'Other linker flags' then the category is recognized and works fine, but honestly don't know why doesn't work without the flag.

Thanks in advance.

Another thing I noticed now is if I add -ObjC on 'Other linker flags' then the category is recognized and works fine

Yep. And there are a variety of similar flags next to that one in the in the ld man page.

but honestly don't know why doesn't work without the flag.

This is basically a disconnect between the dynamic nature of Objective-C and the static nature of the linker. A static library is an archive containing multiple .o files. By default the static linker only integrates a .o into the final binary if it’s referenced by other code. This acts like a primitive form of dead stripping.

However, Objective-C code is often referenced dynamically, which means that the static linker can’t tell whether the code is used or not. The -ObjC option causes the linker to integrate all of the .o files in the static library, regardless of whether it thinks they’re used or not.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"