Cocoa NSManagedObject子类中的自定义Setter
我的NSMAnagedObject中有一个实体依赖于其他实体,因此在阅读了上的文档后,我在我的子类中提出了以下内容Cocoa NSManagedObject子类中的自定义Setter,cocoa,core-data,key-value-observing,Cocoa,Core Data,Key Value Observing,我的NSMAnagedObject中有一个实体依赖于其他实体,因此在阅读了上的文档后,我在我的子类中提出了以下内容 + (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key { NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key]; if ([key isEqualToString:@"assetAmount"]) {
+ (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”,如果更改了包含在KeyPaths ForvaluesAffectingValueForkey中的值,则不会调用setter。我走错方向了吗?我希望setter在每次值更改时都会被调用
NSArray *affectingKeys = @[@"assetAlternativeCur", @"assetAltCur", @"assetCurrency"];
告诉运行时系统这三个因素会影响assetAmount
的值。。。因此,当其中一个更改时,您将收到一个通知,assetAmount
已更改,但其他3个键的设置器不会更改assetAmount
的getter的工作方式。。所以你没有零钱
你可以通过两种不同的方式来强制执行。。您的assetAmount
getter可以是动态的,只需计算值,然后返回它
或者在其他3个键的设置器中,您可以执行以下操作:
self.assetAmount = self.primativeAssetAmount;
但是我会认为这太草率,很可能会导致道路上出现问题…您应该只有一个值,然后是另一个方法,即具有格式化版本的adjustedAssetAmount
温度就是一个例子
其中有一个属性absoluteTemp
,以及C和F的getter
getter for C: => absoluteTemp+273.15
getter for F: => 9/5 * absoluteTemp + 32
如果您有assetAmount值的观察者,或与assetAmount值的绑定,则当影响assetAmount的值发生更改时,这些观察者和绑定将相应更新。然后调用assetAmount getter 在AssetMount获取程序中,可以重新计算要返回的AssetMount 如果您想在每次调用getter时进行计算,那么就完成了 如果要将计算值保存在ivar中,则必须确保直接访问ivar,以避免触发KVO和绑定。(这是第二十二条军规) 如果您不希望getter每次都计算该值,我相信您可以从其他值的setter调用AssetMount的setter。您甚至不需要valuesAffecting之类的东西,因为您将调用setter并触发KVO 从这个意义上讲,您需要keypathsforvaluesfectingvalueforkey:只有在您希望AssetMount getter每次都进行计算时才需要。如果希望将其保存在ivar中,则在其他值更改时使用其setter即可
(另外,如果要执行该路径,您可以实现KeyPathsForvaluesAffectingAssetMount)我确实使用绑定,正如您所指出的,当其他值更改时,会调用AssetMount getter。另外,我让getter执行必要的计算并返回一个新值。但我对你如何实现你的最后一段感到困惑…我如何保存getter返回的这个新值?你有原始值的东西--据我所知,这是获取IVAR核心数据的方法。但现在我想得更多了,这是一个第二十二条军规,不会使事情复杂化,你必须做新的计算,才能知道你是否必须做新的计算。另一种方法是让其他三个影响AssetMount的值的设置程序发出willChangeValueForKey AssetMount并为AssetMount设置新的原语值,然后调用didChangeValueForKey AssetMount,并触发对自动合成getter的调用。我将编辑我的答案。