我有一个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
答案 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");
}
}
}
希望它对你有所帮助......