[英]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.