Objective-C 中的类别不起作用
我正在开发一个需要部署到 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
看起来您的类别确实没有被编译或链接到您使用它的同一目标中。您应该确保 NSData+Base64.m 被标记为由使用它的同一目标编译,方法是获取两个文件的信息并比较它们分配到的目标。
您可以执行的测试是向 NSData+Base64.m 添加一行带有 #error 错误消息的行,这将导致构建在到达该文件时失败。像这样:
然后查看哪个目标无法编译。
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:
Then look and see which target fails to compile.
我对 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.
您是否为您的类别
#import
编辑了头文件?我知道这听起来很简单,但我几乎每次都会忘记。Have you
#import
ed the header file for your category? I know it sounds simple, but I forget nearly every time.有一篇很棒的文章 The Carbon Emitter 关于在 iOS 中处理类别的信息。它详细介绍了处理将类别导入项目的简单方法。
创建一个包含所有类别导入的文件,在本例中为
Extensions.h
:在
AppName-Prefix.pch
中添加导入您的文件: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
:Add import your file in
AppName-Prefix.pch
:就我而言,当我收到此错误时,我只需在编译资源中添加 .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.