What is the best way to solve an Objective-C namespace collision?

Prefixing your classes with a unique prefix is fundamentally the only option but there are several ways to make this less onerous and ugly. There is a long discussion of options here. My favorite is the @compatibility_alias Objective-C compiler directive (described here). You can use @compatibility_alias to “rename” a class, allowing you to name your class using FQDN or some such prefix:

@interface COM_WHATEVER_ClassName : NSObject
@end

@compatibility_alias ClassName COM_WHATEVER_ClassName
// now ClassName is an alias for COM_WHATEVER_ClassName

@implementation ClassName //OK
//blah
@end

ClassName *myClass; //OK

As part of a complete strategy, you could prefix all your classes with a unique prefix such as the FQDN and then create a header with all the @compatibility_alias (I would imagine you could auto-generate said header).

The downside of prefixing like this is that you have to enter the true class name (e.g. COM_WHATEVER_ClassName above) in anything that needs the class name from a string besides the compiler. Notably, @compatibility_alias is a compiler directive, not a runtime function so NSClassFromString(ClassName) will fail (return nil)–you’ll have to use NSClassFromString(COM_WHATERVER_ClassName). You can use ibtool via build phase to modify class names in an Interface Builder nib/xib so that you don’t have to write the full COM_WHATEVER_… in Interface Builder.

Final caveat: because this is a compiler directive (and an obscure one at that), it may not be portable across compilers. In particular, I don’t know if it works with the Clang frontend from the LLVM project, though it should work with LLVM-GCC (LLVM using the GCC frontend).

Leave a Comment