【问题标题】:Unrecognized selector which doesn't appear in source code causes crash未出现在源代码中的无法识别的选择器导致崩溃
【发布时间】:2015-06-29 21:29:31
【问题描述】:

NSString+sha1.h的内容:

#include <CommonCrypto/CommonDigest.h>
#include <Foundation/Foundation.h>

@interface NSString (sha1)

- (NSString *) sha1;

@end

NSString+sha1.m的内容:

#include "NSString+sha1.h"

@implementation NSString (sha1)

- (NSString *) sha1 {
    const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
    NSData *data = [NSData dataWithBytes:cstr length:input.length];

    uint8_t digest[CC_SHA1_DIGEST_LENGTH];

    CC_SHA1(data.bytes, data.length, digest);

    NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2];

    for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
        [output appendFormat:@"%02x", digest[i]];

    return [NSString stringWithString:output];
}

@end

UIImage+RenderBatteryImage.m的内容:

#include "UIImage+RenderBatteryImage.h"
#include "NSString+sha1.h"
[...]
[@"A string (but not this one)" sha1]

当第三个文件的代码运行时,我得到这个错误:

-[__NSCFString sha1]: unrecognized selector sent to instance 0x12ee1caf0

这是什么原因造成的?我可以确认我的任何源文件中都没有大写 SHA1 实例。

【问题讨论】:

标签: ios objective-c theos


【解决方案1】:

我有一个需要验证的假设。在系统日志中,您有以下错误:

-[__NSCFString sha1]: unrecognized selector sent to instance 0x12ee1caf0

看起来您的方法 sha1 未找到并导致崩溃。怎么可能发生?编译器将@"A string (but not this one)" 的对象替换为一些表示常量字符串的内部对象,并且您没有为此特定的常量字符串类型定义类别方法。

以下是我建议用于验证和修正假设的工作流程:

  1. 注释掉执行 sha1 调用的字符串并检查是否没有发生错误
  2. 用实际对象[NSString withString: @"your string"] 替换文字以使编译器超智能

这实际上是一些证据,证明我关于在编译时用常量表示替换字符串的假设是正确的——What is the different between NSCFString and NSConstantString?

【讨论】:

  • 这与他在原始问题中所说的不同。
  • @HotLicks 他说在一个问题中他使用了错误的错误,但在日志中错误是正确的。
  • 那么他应该编辑问题以使其正确。
【解决方案2】:

示例代码,一个简单的自包含方法,只需将其添加到您的类中即可:

// Add Security.framework to the project.
#include <CommonCrypto/CommonDigest.h>

+ (NSString *) sha1:(NSString *)string {
    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableData *hash = [NSMutableData dataWithLength:CC_SHA1_DIGEST_LENGTH];
    CC_SHA1(data.bytes, (CC_LONG)data.length, hash.mutableBytes);

    NSMutableString *hexAscii = [NSMutableString new];
    for(int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++)
        [hexAscii appendFormat:@"%02x", ((uint8_t *)hash.mutableBytes)[i]];

    return [hexAscii copy]; // Make immutable
}

测试(假设方法在Test类中。

NSString *hashHexASCII = [Test sha1:@"test String"];
NSLog(@"hashHexASCII: %@", hashHexASCII);

输出:

hashHexASCII:9269ca2a6a1695eff8d5acd47b57c045698e3ce1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-28
    • 2016-07-05
    • 1970-01-01
    • 2012-08-13
    • 1970-01-01
    • 2012-09-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多