iOS - App在Release中崩溃但在Debug模式下崩溃。 [__NFCString count]:发送到实例xxx的无法识别的选择器

时间:2014-09-09 05:28:41

标签: ios objective-c

我有一个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

2 个答案:

答案 0 :(得分:2)

尽量避免使用Category中的覆盖功能(在您的情况下为valueForKeyPath),这会导致BAD内容。

在上面的代码中,我没有看到你在这里投了一些东西:container = self;(第3行)

尝试逐步调试: 在发布模式下,你无法真正调试,但你可以做这样的内省:

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

答案 1 :(得分:1)

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

- (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");
           }
        }
    }

希望它对你有所帮助......