NSManagedObject子类中的自定义设置器

时间:2014-03-24 17:26:29

标签: cocoa core-data key-value-observing

我的NSMAnagedObject中有一个依赖于其他enitity的权限,所以在阅读了Depend Keys上的文档后,我在我的子类中提出了以下内容

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

    if ([key isEqualToString:@"assetAmount"]) {
        NSArray *affectingKeys = @[@"assetAlternativeCur", @"assetAltCur", @"assetCurrency"];
        keyPaths = [keyPaths setByAddingObjectsFromArray:affectingKeys];
    }
    return keyPaths;
}


- (void)setAssetAmount:(NSDecimalNumber *)assetAmount
{
    [self willChangeValueForKey:@"assetAmount"];

    if ([[self useAlternativeCur] boolValue] == YES) {
        NSDecimalNumber *result;
        result = [[self assetConversionRate] decimalNumberByMultiplyingBy:[self assetAlternativeCur]];
        [self setPrimitiveAssetAmount:result];
    } else {
        [self setPrimitiveAssetAmount:assetAmount];
    }
    [self didChangeValueForKey:@"assetAmount"];
}

我的问题是,当我直接更改“assetAmount”值时,只会调用setter“setAssetAmount”,如果更改keyPathsForValuesAffectingValueForKey中包含的值,则不会调用setter。我是以错误的方式来做这件事的吗?我希望每次任何值改变时都会调用setter。

2 个答案:

答案 0 :(得分:1)

NSArray *affectingKeys = @[@"assetAlternativeCur", @"assetAltCur", @"assetCurrency"];

告诉运行时系统这3个其他因素会影响assetAmount的值...所以当其中一个更改时,您会收到assetAmount更改的通知,但是其他3的设置者密钥不会改变assetAmount的吸气剂的工作方式..所以你不会有任何改变......

您可以通过几种不同的方式强制执行此操作..您的assetAmount getter可能是动态的,只需计算该值然后返回它。

或在其他3个键的setter中,您可以执行以下操作:

self.assetAmount = self.primativeAssetAmount;

但我认为这很草率,可能会引发问题...你应该只有一个值,然后是另一个方法,即具有格式化版本的adjustedAssetAmount ......

一个例子就是温度。

你有property absoluteTemp,以及C和F的吸气剂。

getter for C: => absoluteTemp+273.15

getter for F: => 9/5 * absoluteTemp + 32

答案 1 :(得分:1)

如果您拥有assetAmount值的观察者,或者绑定到assetAmount的值,那么当影响assetAmount的值发生更改时,这些观察者和绑定将得到适当更新。然后调用assetAmount getter

在assetAmount getter中,您可以重新计算要返回的assetAmount。

如果你想在每次调用getter时进行计算,你就完成了。

如果你想在ivar中保存计算的值,那么你必须确保直接访问ivar以避免KVO和绑定触发。(是一个catch-22)< / p>

如果您不希望getter每次都计算该值,我相信您可以从setter中为其他值调用assetAmount的setter。你甚至不需要值影响东西,因为你正在调用setter并触发KVO。

从这个意义上讲,如果您希望assetAmount getter每次都进行计算,那么您只需要keyPathsForValuesAffectingValueForKey: 。如果您希望将其保存在ivar中,只需在其他值更改时使用其setter。

(另外,如果你要去那条路线,你可以实现keyPathsForValuesAffectingAssetAmount)