I have created a static library to house some of my code like categories.
I have a category for UIViews in "UIView-Extensions.h" named Extensions.
In this category I have a method called:
- (void)fadeOutWithDelay:(CGFloat)delay duration:(CGFloat)duration;
Calling this method works fine on the simulator on Debug configuration.
However, if try to run the app on the device I get a NSInvalidArgumentException:
[UIView fadeOutWithDelay:duration:]: unrecognized selector sent to instance 0x1912b0 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[UIView fadeOutWithDelay:duration:]: unrecognized selector sent to instance 0x1912b0
It seems for some reason UIView-Extensions.h is not being included in the device builds.
What I have checked/tried
I did try to include another category for NSString, and had the same issue.
Other files, like whole classes and functions work fine. It is an issue that only happens with categories.
I did a clean all targets, which did not fix the problem.
I checked the static library project, the categories are included in the target's "copy headers" and "compile sources" groups.
The static library is included in the main projects "link binary with library" group.
Another project I have added the static library to works just fine.
I deleted and re-added the static library with no luck
-ObjC linker flag is set
Any ideas?
nm output
libFJSCodeDebug.a(UIView-Extensions.o): 000004d4 t -[UIView(Extensions) changeColor:withDelay:duration:] 00000000 t -[UIView(Extensions) fadeInWithDelay:duration:] 000000dc t -[UIView(Extensions) fadeOutWithDelay:duration:] 00000abc t -[UIView(Extensions) firstResponder] 000006b0 t -[UIView(Extensions) hasSubviewOfClass:] 00000870 t -[UIView(Extensions) hasSubviewOfClass:thatContainsPoint:] 000005cc t -[UIView(Extensions) rotate:] 000002d8 t -[UIView(Extensions) shrinkToSize:withDelay:duration:] 000001b8 t -[UIView(Extensions) translateToFrame:delay:duration:] U _CGAffineTransformRotate 000004a8 t _CGPointMake U _CGRectContainsPoint U _NSLog U _OBJC_CLASS_$_UIColor U _OBJC_CLASS_$_UIView U ___CFConstantStringClassReference U ___addsf3vfp U ___divdf3vfp U ___divsf3vfp U ___extendsfdf2vfp U ___muldf3vfp U ___truncdfsf2vfp U _objc_enumerationMutation U _objc_msgSend U _objc_msgSend_stret U dyld_stub_binding_helper
The only solution that worked was to include:
"-all_load"
in other linker flags.
EDIT: Be sure to add this flag to the project including the static library, not to the static library itself.
I know this isn't the correct method, but it is working for now.
It maybe a OS 3.0 issue since this was the work around for Three20 as well.
Unfortunately, due to the what categories work and the dynamic nature of the Objective-C runtime, not everything works well with static libraries. The reason you get this error is that the category implementation in the static library is never actually linked into the executable image because the compiler has no way of knowing that the implementation code will be needed at run-time.
In order to cure this, you can force the linker to copy object files from a static archive for any and all Objective-C Class and Category images. The downside is that your executable will include image code for classes that you may not be using at all. To get the linker to include the category code, add -ObjC
to the OTHER_LD_FLAGS
build setting in Xcode. Your category implementation will now be copied from the static archive to your executable and you won't get the runtime exception.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With