2013-01-21 64 views
1

是否有可能使用Obj-C鍵值編碼進行算術運算?我正在尋找這樣的事情:算術運算符和鍵值編碼

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

還是你必須實現一個屬性,手動添加兩個值?

+0

什麼是你的確切需要什麼? –

+0

我不這麼認爲。我認爲這是你給的字符串變量,將被保存。我想現在你可以自己嘗試一切。 –

回答

3

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

你可以做算術處理字符串,然後把它傳遞給[obj valueforKeyPath:...]爲:

NSString *[email protected]"3"; 
NSString *[email protected]"5"; 

NSString *formula = [NSString stringWithFormat:@"%@+%@",val1,val2]; 

NSExpression *exp = [NSExpression expressionWithFormat:formula]; 
NSNumber *resultForCustomFormula = [exp expressionValueWithObject:nil context:nil]; 

NSLog(@"%f", [resultForCustomFormula floatValue]); 
+0

非常感謝!我會看看NSExpression,看看我能用它做些什麼。 – Trenskow

3

我用NSExpression例如AKV了創建這個NSObject的類別。

這擴展valueForKeyPath:所以它支持表情是這樣的:

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

或每例如:

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

類別

#import <objc/runtime.h> 

@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 
+1

swizzle swizzle .. +1 –