繁体   English   中英

iOS-应用在“发行版”中崩溃,但不在“调试”模式下崩溃。 [__NFCString count]:无法识别的选择器已发送到实例xxx

[英]iOS - App crashes in Release but not in Debug mode. [__NFCString count]: unrecognized selector sent to instance xxx

我有一个NSObject类别,其中已经套用了valueForKeyPath:方法。 如果keyPath包含[] ,则假定该对象是一个array并为给定索引调用objectAtIndex:方法。

+ (void)load {
    Method original, swizzled;

    original = class_getInstanceMethod(self, @selector(valueForKeyPath:));
    swizzled = class_getInstanceMethod(self, @selector(valueForExtendedKeyPath:));
    method_exchangeImplementations(original, swizzled);
}

实现方式:

- (id)valueForExtendedKeyPath:(NSString * __autoreleasing *)keyPath {
token = keyPath; 
container = self;
if([token hasPrefix:@"["]) {
    NSExpression *expression;
    NSInteger index, count;

    count = [container count];
    token = [token substringWithRange:NSMakeRange(1, token.length - 2)];
    token = [token stringByReplacingOccurrencesOfString:@"@lastIndex" withString:[NSString stringWithFormat:@"%lu", (unsigned long)count - 1]];

    expression = [NSExpression expressionWithFormat:token];
    index = [[expression expressionValueWithObject:nil context:nil] integerValue];
    if(index >= 0 && index < count) {
        value = container[index];
    }
}

}

我确保该容器始终是NSArray debug mode ,应用程序运行正常,但在Release mode ,应用程序崩溃并显示以下错误:

[__NFCString count]: unrecognized selector sent to instance xxx

尝试避免使用Category重写功能(在您的情况下为valueForKeyPath ),这将导致出现BAD问题。

在上面的代码中,我看不到您在此处强制转换内容: container = self; (第三行)

尝试逐步调试:在发布模式下,您无法真正调试,但是可以进行如下自省:

NSLog(@"isString:%i", [self isKindOfClass:[NSString class]]);

到目前为止,您可以使用以下代码避免崩溃。.(检查容器类型的条件)

- (id)valueForExtendedKeyPath:(NSString * __autoreleasing *)keyPath 
{
    token = keyPath; 
    container = self;
    if([token hasPrefix:@"["]) 
    {
        NSExpression *expression;
        NSInteger index, count;

            if(container isKindOfClass:[NSArray class])
            {
            count = [container count];
            token = [token substringWithRange:NSMakeRange(1, token.length - 2)];
            token = [token stringByReplacingOccurrencesOfString:@"@lastIndex" withString:[NSString stringWithFormat:@"%lu", (unsigned long)count - 1]];

            expression = [NSExpression expressionWithFormat:token];
            index = [[expression expressionValueWithObject:nil context:nil] integerValue];
            if(index >= 0 && index < count) 
            {
                value = container[index];
            }
            }
          else
           {
               NSLog(@"The container is string");
           }
        }
    }

希望对您有帮助...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM