导致无法识别的选择器的Objective-C类别


69

我的项目有一个UIImage我要从另一个类调用的类别函数。我正确地导入了图像类别的头文件,并且我得到了要编译的项目而没有任何警告。

问题是,当我调用UIImagecategory函数时,看到带有的无法识别的选择器错误NSInvalidArgumentException。如果正确链接了所有内容,为什么会看到此消息?

#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

调用它的文件:

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

引发异常:

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

1
请提供代码和异常详细信息。没有那几乎不可能回答。
Matthias Bauch 2010年

的声明imageNamedTT:也将很有用。
James Huddleston 2010年

1
可能是您的实例实际上是另一个类吗?
GeorgSchölly10年

ps。这是一个奇怪的问题,很长一段时间以来,我的工作情况都非常好,有些事情还是一团糟。
devinross

可能只是我很笨,但是您已经声明了imageNamed: and then the implementation for imageNamedDR:`,但是此方法未在标头中声明。(显然是旧的,您现在可能已经解决了该问题)。这只是一个错字还是一个实际的问题?
Popeye

Answers:


219

几种可能性:

  1. 您没有链接UIImage+TTShare.m到目标。因此,尽管拥有标头,但无需编译实现。
  2. 如果这是静态库的一部分,则需要为应用程序与库的链接添加-all_load到“其他链接器标记”构建设置。

作为记录,我想我搞砸了我的静态库目标。
devinross

26
感谢您指出静态库的问题。developer.apple.com/library/mac/#qa/qa1490/_index.html包含更多信息。为了清楚起见,您必须将该标志添加到包含静态库的应用程序的链接器标志中,而不是在构建静态库本身时。
Bob Whiteman '10

1
stackoverflow.com/a/8437129/1972476中所述, Xcode可能也是罪魁祸首。我无意中使用类模板创建了文件,使用类别模板删除了这些文件并重新创建了相同名称的文件。重命名实现后(返回),它可以正常工作。
2013年

您的意思是-all_load客户端应用程序的构建设置中,而不是在构建静态库时,对吗?那对我有用。
Nicolas Miari

7
使用之前,请-all_load确保尝试仅添加即可-ObjC解决问题。所有负载都会不必要地增加可执行文件的大小。
LearnCocos2D 2015年

10

如果要使用类别方法,则必须将-ObjC添加到APP的“其他链接器标志”构建设置中。


哇。当然。在我的情况下,我在主应用程序的子项目中有一个类别,该类别仅在子项目中使用,但是在主应用程序中添加-ObjC可以解决该问题。谢谢。
Orion elenzil

6

我遇到了同样的问题,因此也必须应用此修复程序。我的NSDate-Extensions.m源文件未编译,因此我必须进入项目设置,然后选择适当的目标,然后单击“构建阶段”选项卡,然后展开“编译源”项,然后单击+符号并手动添加我的NSDate-Extensions.m文件。


0

我收到此错误消息,并且正在使用Cocoapods。要修复该错误,我只需要pod install再次调用即可正确创建所有必要的链接。


0

另一种可能性。

您具有类别的实现,但没有接口。我的意思是您忘记在* .h中声明您类别的接口。


0

还有另一种可能性:

承认这一点几乎令人尴尬,但是以防万一有人犯了同样愚蠢的错误:

我正在将代码从一个项目复制到另一个项目,并且错误地将相同的源代码粘贴到了.h文件和.m文件中(在这两个文件中,我都放置了用于.h文件的代码)。我修复了.m文件,结果正常。


0

可能是因为您编写imageNamed而不是imageNamedDR在界面中编写。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.