Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling method on category included from iPhone static library causes NSInvalidArgumentException

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 
like image 289
Corey Floyd Avatar asked May 31 '09 21:05

Corey Floyd


2 Answers

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.

like image 85
Corey Floyd Avatar answered Oct 20 '22 18:10

Corey Floyd


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.

like image 40
Jason Coco Avatar answered Oct 20 '22 17:10

Jason Coco