70

My project has a UIImage category function that I want to call from another class. I properly import the header file for the image category and I get the project to compile with no warning.

The problem is that when I call the UIImage category function I seen an unrecognized selector error with a NSInvalidArgumentException. Why am I seeing this if I've properly linked everything?

#import <UIKit/UIKit.h>

@interface UIImage (DRShare)

+ (UIImage*) imageNamed:(NSString*)name;

@end


@implementation UIImage (DRShare)

+ (UIImage*) imageNamedDR:(NSString*)name{

    CGFloat s = 1.0f;
    if([[UIScreen mainScreen] respondsToSelector:@selector(scale)]){
        s = [[UIScreen mainScreen] scale];
    }

    NSString *path = [NSString stringWithFormat:@"%@%@%@.png",kImagesPath,name,s > 1 ? @"@2x":@""];
    return [UIImage imageWithContentsOfFile:DRBUNDLE(path)];
}

@end

file that calls it:

        backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamedDR:@"Share Popup Background"]];

exception raised:

2010-10-22 11:51:02.880 Stuff[11432:207] +[UIImage imageNamedDR:]: unrecognized selector sent to class 0x1f8e938
2010-10-22 11:51:02.883 Stuff[11432:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[UIImage imageNamedDR:]: unrecognized selector sent to class 0x1f8e938'
*** Call stack at first throw:
(
    0   CoreFoundation                      0x02e65b99 __exceptionPreprocess + 185
    1   libobjc.A.dylib                     0x02fb540e objc_exception_throw + 47
    2   CoreFoundation                      0x02e6776b +[NSObject(NSObject) doesNotRecognizeSelector:] + 187
    3   CoreFoundation                      0x02dd72b6 ___forwarding___ + 966
    4   CoreFoundation                      0x02dd6e72 _CF_forwarding_prep_0 + 50
    5   TapTapShare                         0x0001291c -[DRShareViewController backgroundView] + 127
    6   TapTapShare                         0x00012343 -[DRShareViewController loadView] + 639
    7   UIKit                               0x0044f54f -[UIViewController view] + 56
    8   UIKit                               0x0044d9f4 -[UIViewController contentScrollView] + 42
    9   UIKit                               0x0045d7e2 -[UINavigationController _computeAndApplyScrollContentInsetDeltaForViewController:] + 48
    10  UIKit                               0x0045bea3 -[UINavigationController _layoutViewController:] + 43
    11  UIKit                               0x0045d12d -[UINavigationController _startTransition:fromViewController:toViewController:] + 524
    12  UIKit                               0x00457ccd -[UINavigationController _startDeferredTransitionIfNeeded] + 266
    13  UIKit                               0x00574b55 -[UILayoutContainerView layoutSubviews] + 226
    14  QuartzCore                          0x02616481 -[CALayer layoutSublayers] + 177
    15  QuartzCore                          0x026161b1 CALayerLayoutIfNeeded + 220
    16  QuartzCore                          0x026160bd -[CALayer layoutIfNeeded] + 111
Meet Doshi
  • 4,241
  • 10
  • 40
  • 81
devinross
  • 2,816
  • 6
  • 34
  • 34
  • 1
    please provide code and Exception details. Quite impossible to answer without that. – Matthias Bauch Oct 22 '10 at 15:50
  • The declaration of `imageNamedTT:` would be useful too. – James Huddleston Oct 22 '10 at 15:57
  • 1
    Could it be, that your instance is actually a different class? – Georg Schölly Oct 22 '10 at 15:58
  • ps. this is a weird issue, i've had it work perfectly fine for a long time and something just went haywire. – devinross Oct 22 '10 at 16:02
  • Probably just me being stupid but you have declared `imageNamed: and then the implementation for `imageNamedDR:` but this method isn't declared in the header. (Obviously old and you have probably fixed the issue by now). Was this just a typo or was an actual issue? – Popeye Apr 09 '15 at 10:53

8 Answers8

222

A couple possibilities:

  1. You did not link UIImage+TTShare.m into your target. So while you have the header, you're not compiling the implementation.
  2. If this is part of a static library, you need to add -all_load to the Other Linker Flags build setting for the app linking against the library.
Dov
  • 15,530
  • 13
  • 76
  • 177
Dave DeLong
  • 242,470
  • 58
  • 448
  • 498
  • For the record, I think i messed up my static library target up. – devinross Oct 22 '10 at 16:27
  • 27
    Thanks for pointing out the problem with static libraries. http://developer.apple.com/library/mac/#qa/qa1490/_index.html has more information. To be clear, you have to add that flag to the linker flags for the app that's including the static library, not when building the static library itself. – Bob Whiteman Oct 01 '11 at 00:10
  • 1
    As noted in http://stackoverflow.com/a/8437129/1972476 Xcode may also be the culprit here. I had inadvertently created the files with the class template, deleted these and recreated files with the same name using the category template. After renaming the implementation (and back) it worked. – Seán Labastille Mar 27 '13 at 17:52
  • You mean `-all_load` in the build settings of **the client app**, **not** when building the static library right? That's what worked for me. – Nicolas Miari May 14 '14 at 08:46
  • 8
    Before using `-all_load` be sure to try whether only adding `-ObjC` fixes the problem. All load will unnecessarily increase the executable's size. – CodeSmile Aug 20 '15 at 18:29
  • `into your target`.. especially when you have more than one target. Auto added to one, but not all! – James Webster Sep 23 '15 at 15:26
  • I've noticed that in my case ( it's a library ) it's enough adding the `-all_load` in the project, no in the target. – xarly May 13 '16 at 14:34
  • I highly recommend @LearnCocos2D 's suggestion. Only use -all_load if you really need it. See [this answer](http://stackoverflow.com/questions/2567498/objective-c-categories-in-static-library). – Dean Kelly Jun 24 '16 at 18:50
  • Worked by removing that Lib first and then add it back. (Hint #1 helps) – Linc Aug 04 '17 at 02:38
15

If you want to use Category method, you must add -ObjC to the Other Linker Flags build setting of your APP.

ling
  • 171
  • 1
  • 2
  • wow. of course. In my situation i had a category in a sub-project of my main app, which was used only in the sub-project, but adding *-ObjC* to the main app fixed it. thank you. – orion elenzil Jan 10 '19 at 17:00
7

I had the same issue and had to apply this fix as well. My NSDate-Extensions.m source file wasn't compiling so I had to go into Project Settings, then select the appropriate target, then click the "Build Phases" tab, then expand the "Compile Sources" items, then click the + symbol and manually add my NSDate-Extensions.m file.

Clive Paterson
  • 1,663
  • 1
  • 15
  • 10
1

I had this error message and I am using Cocoapods. To fix the error, I just needed to call pod install again to create all the necessary linking correctly.

disco crazy
  • 31,313
  • 12
  • 80
  • 83
0

Another possibility.

You have the implementation of category but do not have an interface. I mean you forgot to declare in *.h the interface of your category.

Voda Ion
  • 3,426
  • 2
  • 16
  • 18
0

Yet another possibility:

This is almost too embarrassing to admit, but just in case someone might have done the same silly mistake:

I was copying code from one project to another, and by mistake I had pasted the same source code in the .h file and the .m file (in both I had put the code meant for the .h file). I fixed my .m file and it worked.

Nikolay Suvandzhiev
  • 8,465
  • 6
  • 41
  • 47
0

May be because you write imageNamed instead of imageNamedDR in the interface..

Meet Doshi
  • 4,241
  • 10
  • 40
  • 81
Hlung
  • 13,850
  • 6
  • 71
  • 90
0

The sdk hybrid project created on the basis of oc will crash when it is called by the swift file in the sdk-related hybrid demo project, prompting that the oc classification method in the sdk cannot be found. I try to put the compiled package in the link binary with libraries(build phase-link binary with libraries), it works! It is not enough to just set the dependencies of the demo to associate the SDK. It can be regarded as a pit of mixed sdk and mixed demo project!