views:

2494

answers:

3

Even though Interface Builder is aware of a MyClass, I get an error when starting the application.

This happens when MyClass is part of a library, and does not happen if I compile the class directly in the application target.

+4  A: 

Despite the "Unknown class MyClass in Interface Builder file." error printed at runtime, this issue has nothing to do with Interface Builder, but rather with the linker, which is not linking a class because no code uses it directly.

When the .nib data (compiled from the .xib) is loaded at runtime, MyClass is referenced using a string, but the linker doesn't analyze code functionality, just code existence, so it doesn't know that. Since no other source files references that class, the linker optimizes it out of existence when making the executable. So when Apple's code tries to load such a class, it can't find the code associated with it, and prints the warning.

The hack I've been using is to add an empty static routine like:

+(void)_keepAtLinkTime;

which does nothing, but that I call once, such as:

int main( int argc, char** argv )
{
   [MyClass _keepAtLinkTime];
   // Your code.
}

This forces the linker to keep the whole class, and the error disappears.

Of course, you can call this in any location of your code. I guess it could even be in unreachable code. The idea is to fool the linker into thinking that MyClass is used somewhere so that it isn't so aggressive in optimizing it out.

jhoule
The .xib data isn't loaded at runtime. The IB compiler compiles the xib to a nib; the nib is what gets loaded at runtime.
Peter Hosey
Good point. I edited my answer accordingly.
jhoule
+1  A: 

You can fix this by setting the ObjC linker flag. See the following forum post for details:

http://support.mobclix.com/forums/65895/entries/95353

MZamkow
Indeed, and there are also other possible flags, such as '-all_load'.See my post in Xcode's mailing list: http://lists.apple.com/archives/Xcode-users/2010/Jan/msg00308.htmlNote that these flags will bring all of the static library's symbols into the executable, potentially bloating it. My approach has the advantage of keeping the final binary to a minimum, but the manual approach is definitely not ideal.But as someone posted in the mailing list's thread, this is the nature of Objective C (and its dynamic binding).
jhoule
A: 

Not only in project settings, but in Target setting also u have to add -all_load -ObjC flags..

http://stackoverflow.com/questions/2431187/core-plot-unknown-class-cplayerhostingview-in-interface-builder-file/3012320#3012320

Sijo