CoreData属性值基于其他属性

时间:2014-07-09 18:06:50

标签: cocoa core-data nsmanagedobject

我有一些CorData实体的属性,这些属性基于其他属性的值。例如,transactionTotalValue = transactionPrice * transactionQuantity。目前我将NSManagedObject子类化并创建了像这样的自定义setter

- (void)setTransactionQuantity:(NSDecimalNumber *)transactionQuantity
{
    [self willChangeValueForKey:@"transactionQuantity"];
    [self setPrimitiveValue:transactionQuantity forKey:@"transactionQuantity"];
    [self didChangeValueForKey:@"transactionQuantity"];
    [self updateTotalValue];
}

- (void)setTransactionPrice:(NSDecimalNumber *)transactionPrice
{
    [self willChangeValueForKey:@"transactionPrice"];
    [self setPrimitiveValue:transactionPrice forKey:@"transactionPrice"];
    [self didChangeValueForKey:@"transactionPrice"];
    [self updateTotalValue];
}

- (void)updateTotalValue
{
    self.transactionTotalValue = [self.transactionQuantity decimalNumberByMultiplyingBy:[NSDecimalNumber decimalNumberWithDecimal:[self.transactionPrice decimalValue]]];
}

这是一种可以接受的方式吗?如果不是这种情况的最佳做法?

另一种选择是使用KVO如下

- (NSDecimalNumber *)transactionTotalValue
{
    [self willAccessValueForKey:@"transactionTotalValue"];
    NSDecimalNumber *total = [self.transactionQuantity decimalNumberByMultiplyingBy:[NSDecimalNumber decimalNumberWithDecimal:[self.transactionPrice decimalValue]]];
    [self didChangeValueForKey:@"transactionTotalValue"];
    return total;
}


+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key
{
    NSSet *keypaths = [super keyPathsForValuesAffectingValueForKey:key];

    if ([key isEqualToString:@"transactionTotalValue"]) {
        NSArray *affectingKeys = @[@"transactionQuantity", @"transactionPrice"];
        keypaths = [keypaths setByAddingObjectsFromArray:affectingKeys];
    }
    return keypaths;
}

这是更好的选择吗?

1 个答案:

答案 0 :(得分:1)

属性transactionTotalValue完全取决于其他两个属性。 将其声明为只读的非原子属性。

@property (nonatomic,readonly) id transactionTotalValue;

然后,您可以实现getter。

- (id)transactionTotalValue 
    {
        //check for non-existent needed properties and handle here

        return [self.transactionQuantity 
        decimalNumberByMultiplyingBy:[NSDecimalNumber 
        decimalNumberWithDecimal:[self.transactionPrice decimalValue]]];
    }

还覆盖影响依赖属性的键的类方法。

+ (NSSet *)keyPathsForValuesAffectingTransactionTotalValue
    {
        return [NSSet setWithObjects:@"transactionQuantity", @"transactionPrice", nil];
    }

如果您要通过绑定更新表源,则会根据需要重新读取transactionTotalValue属性。通过使其成为只读,您将能够避免任何setter方法。