Objective-C 中的类别不起作用

发布于 2024-10-01 14:16:03 字数 1702 浏览 0 评论 0原文

我正在开发一个需要部署到 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 (单独和一起)但无济于事。我真的很感激有关如何让这个选择器工作的一些指导。

谢谢!

I'm developing an iOS application that needs to deploy to iOS 3.1.3. I need to extend some of the functionality of the NSData class and am using the following code inside NSData+Base64 (truncated to show the interesting part):

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

However, when I try to message this selector:

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

I get the following error:

 -[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'

I read a lot about iOS 3.1.x having problems with categories. I tried adding the flags -all_load and -ObjC (both separately and together) to no avail. I would really appreciate some direction of how to get this selector to work.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

白云悠悠 2024-10-08 14:16:03

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

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

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

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

It really seems like your category isn't being compiled or linked into the same target that you're using it from. You should make sure that NSData+Base64.m is marked to be compiled by the same target that it's being used from by getting info on the two files and comparing the targets they're assigned to.

A test you can perform is to add a line with an #error error message to NSData+Base64.m, which will cause the build to fail when it gets to that file. Like this:

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

Then look and see which target fails to compile.

昨迟人 2024-10-08 14:16:03

我对 ARC 项目也有同样的问题,该项目与具有类别扩展的非 ARC 模块链接。

通过在父 ARC 项目中添加“其他链接器标志:-all_load”修复了该问题。

I had the same issue with ARC project which was linking with non-ARC module having category extension.

Fixed the issue by adding "Other Linker Flags: -all_load" in parent ARC project.

温柔一刀 2024-10-08 14:16:03

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

Have you #imported the header file for your category? I know it sounds simple, but I forget nearly every time.

微凉 2024-10-08 14:16:03

有一篇很棒的文章 The Carbon Emitter 关于在 iOS 中处理类别的信息。它详细介绍了处理将类别导入项目的简单方法。

创建一个包含所有类别导入的文件,在本例中为 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

There is a great post on The Carbon Emitter about about handling categories in iOS. It details an easy way to handle importing categories to your project.

Make a file containing all of your category imports, in this example it is Extensions.h:

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

Add import your file in 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
庆幸我还是我 2024-10-08 14:16:03

就我而言,当我收到此错误时,我只需在编译资源中添加 .m 文件,然后它就可以工作了。这可以通过选择目标项目->构建阶段->编译源来实现。然后单击左下角的 + 按钮。在这种情况下,您可以将“NSData+Base64.m”文件添加到编译源中。然后清理项目并运行。我想这可能会有所帮助。

In My case when I got this error I simply added the .m file in the Compiled resources, and it get worked. This can be achieved by selecting target project->Build Phases->Compile Sources. Then you click on the + button from its bottom left. In this case you may add 'NSData+Base64.m' file to the compile sources. Then you clean your project and run. I guess this may help.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文