Objective-C中的类别不起作用

时间:2010-11-09 20:04:19

标签: objective-c ios categories

我正在开发一个需要部署到iOS 3.1.3的iOS应用程序。我需要扩展NSData类的一些功能,并在NSData + Base64中使用以下代码(截断以显示有趣的部分):

的NSData + Base64.h

[...]

@interface NSData (Base64)

+ (NSData *)dataFromBase64String:(NSString *)aString;
- (NSString *)base64EncodedString;

@end

的NSData + Base64.m

@implementation NSData (Base64)

[...]

//
// base64EncodedString
//
// Creates an NSString object that contains the base 64 encoding of the
// receiver's data. Lines are broken at 64 characters long.
//
// returns an autoreleased NSString being the base 64 representation of the
//  receiver.
//
- (NSString *)base64EncodedString
{
    size_t outputLength;
    char *outputBuffer =
        NewBase64Encode([self bytes], [self length], true, &outputLength);

    NSString *result =
        [[[NSString alloc]
            initWithBytes:outputBuffer
            length:outputLength
            encoding:NSASCIIStringEncoding]
        autorelease];
    free(outputBuffer);
    return result;
}

@end

然而,当我尝试给这个选择器发消息时:

NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
NSString *hash = [HMAC base64EncodedString];

我收到以下错误:

 -[NSConcreteData base64EncodedString]: unrecognized selector sent to instance 0x6146e70
2010-11-09 13:44:41.443 SpringboardApplication[21318:40b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSConcreteData base64EncodedString]: unrecognized selector sent to instance 0x6146e70'

我读了很多关于iOS 3.1.x的类别问题。我尝试添加标记-all_load-ObjC(单独和一起)无济于事。我真的很感激如何让这个选择器工作。

谢谢!

5 个答案:

答案 0 :(得分:19)

您的类别似乎没有被编译或链接到您正在使用它的同一目标。您应该确保NSData + Base64.m被标记为由使用它的同一目标编译,方法是获取两个文件的信息并比较它们分配给它们的目标。

您可以执行的测试是向NSData + Base64.m添加带有#error错误消息的行,这将导致构建在到达该文件时失败。像这样:

#error We're now compiling NSData+Base64.m

然后查看哪个目标无法编译。

答案 1 :(得分:7)

我在ARC项目中遇到了同样的问题,该项目与具有类别扩展名的非ARC模块相关联。

通过在父ARC项目中添加“Other Linker Flags:-all_load”来解决此问题。

答案 2 :(得分:2)

您是否#import编辑了类别的标题文件?我知道这听起来很简单,但我几乎每次都会忘记。

答案 3 :(得分:2)

关于在iOS中处理类别,The Carbon Emitter上有一篇很棒的帖子。它详细介绍了一种处理将类别导入项目的简单方法。

制作一个包含所有类别导入的文件,在此示例中为Extensions.h

#import "NSDate+Formatting.h"
#import "UIFonts+MyFonts.h"
#import "UIViewController+Tourbot.h"

AppName-Prefix.pch中添加导入文件:

#import <Availability.h>

#ifndef __IPHONE_3_0
#warning "This project uses features only available in iPhone SDK 3.0 and later."
#endif

#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
#import <CoreText/CoreText.h>
#import "Extensions.h" // Add import here
#endif

答案 4 :(得分:2)

在我的情况下,当我收到此错误时,我只是在Compiled资源中添加.m文件,然后就可以了。这可以通过选择目标项目 - > Build Phases-&gt; Compile Sources来实现。然后单击左下角的+按钮。在这种情况下,您可以将“NSData + Base64.m”文件添加到编译源。然后你清理你的项目并运行。我想这可能有所帮助。

相关问题