算术运算符和键值编码

是否可以使用Obj-C键值编码进行算术运算? 我正在寻找这样的东西:

[obj valueForKeyPath:@"(val1+val2)"] 

或者你必须实现一个手动添加两个值的属性?

使用KVC的算法是不可能的。

您可以使用字符串进行算术运算,然后将其传递给[obj valueforKeyPath:...]如下所示:

 NSString *val1=@"3"; NSString *val2=@"5"; NSString *formula = [NSString stringWithFormat:@"%@+%@",val1,val2]; NSExpression *exp = [NSExpression expressionWithFormat:formula]; NSNumber *resultForCustomFormula = [exp expressionValueWithObject:nil context:nil]; NSLog(@"%f", [resultForCustomFormula floatValue]); 

我使用了AKV给出的NSExpression示例来创建这个NSObject类别。

这扩展了valueForKeyPath:所以它支持这样的表达式:

 [obj valueForKeyPath:@"(val1+val2)"]; 

或者每个例子:

 [obj valueForKeyPath:@"@min.(val1+val2)"]; 

类别

 #import  @implementation NSObject (KVCExtension) #pragma mark - Initializing a Class + (void)load { SEL valueForKeyPath = @selector(valueForKeyPath:); SEL extendedValueForKeyPath = @selector(extendedValueForKeyPath:); Method valueForKeyPathMethod = class_getInstanceMethod([self class], valueForKeyPath); Method extendedValueForKeyPathMethod = class_getInstanceMethod([self class], extendedValueForKeyPath); method_exchangeImplementations(valueForKeyPathMethod, extendedValueForKeyPathMethod); } #pragma mark - Key-Value Coding - (id)extendedValueForKeyPath:(NSString *)keyPath { /* NOTICE: +load exchanged this method with valueForKey: !!! Thus calling extendedValueForKeyPath: now means we're calling the old valueForKeyPath: method and vice versa. */ if ([keyPath length] > 0 && [keyPath characterAtIndex:0] == '(') { if ([self isKindOfClass:[NSArray class]]) { NSMutableArray *results = [[NSMutableArray alloc] init]; for (id obj in (NSArray *)self) [results addObject:[obj valueForKeyPath:keyPath]]; return [results copy]; } else { NSRegularExpression *regExp = [NSRegularExpression regularExpressionWithPattern:@"[A-Za-z0-9_\\.]*" options:0 error:nil]; NSMutableString *mKeyPath = [keyPath mutableCopy]; [regExp enumerateMatchesInString:mKeyPath options:0 range:NSMakeRange(0, [keyPath length]) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) { NSRange range = [[result resultByAdjustingRangesWithOffset:[mKeyPath length] - [keyPath length]] range]; if (range.length > 0) { NSString *key = [mKeyPath substringWithRange:range]; NSString *val = [[self extendedValueForKeyPath:key] stringValue]; [mKeyPath replaceCharactersInRange:range withString:val]; } }]; NSExpression *expression = [NSExpression expressionWithFormat:mKeyPath]; return [expression expressionValueWithObject:nil context:nil]; } } else return [self extendedValueForKeyPath:keyPath]; } @end