NSManagedObject 子类中的自定义设置器
Posted
技术标签:
【中文标题】NSManagedObject 子类中的自定义设置器【英文标题】:Custom Setter in NSManagedObject Subclass 【发布时间】:2014-03-24 17:26:29 【问题描述】:我的 NSManagedObject 中有一个依赖于其他实体的实体,因此在阅读了 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"];
我的问题是设置器“setAssetAmount”只有在我直接更改“assetAmount”值时才会被调用,如果更改 keyPathsForValuesAffectingValueForKey 中包含的值,则设置器不会被调用。我会以错误的方式解决这个问题吗?我希望设置器在每次任何值更改时都会被调用。
【问题讨论】:
【参考方案1】:如果您有assetAmount 值的观察者,或对assetAmount 值的绑定,那么当影响assetAmount 的值发生变化时,这些观察者和绑定会相应地更新。然后调用assetAmount getter。
在assetAmount getter中,你可以重新计算你想要返回的assetAmount。
如果您想在每次调用 getter 时都进行计算,那么您就完成了。
如果你想将计算的值保存在 ivar 中,那么你必须确保直接访问 ivar 以避免触发 KVO 和绑定。(是一个 catch-22)
如果您不希望 getter 每次都计算值,我相信您可以从 setter 中调用assetAmount 的 setter 来获取其他值。你甚至不需要 valuesAffecting 的东西,因为你会调用 setter 并触发 KVO。
从这个意义上说,如果您希望您的assetAmount getter 每次都进行计算,则需要 keyPathsForValuesAffectingValueForKey: 。如果您希望将其保存在 ivar 中,只需在其他值更改时使用它的 setter。
(另外,如果你要走那条路,你可以实现 keyPathsForValuesAffectingAssetAmount)
【讨论】:
我确实使用了绑定,就像您指出的那样,当其他值发生变化时,将调用assetAmount getter。此外,我让 getter 执行必要的计算并返回一个新值。但我对你将如何实现最后一段感到困惑......我将如何保存 getter 返回的这个新值? 据我所知,您可以使用primitiveValue 的东西——这是获取具有核心数据的ivars 的方法。但现在我想得更多,这是一个第 22 条规则,没有复杂的事情,你必须做新的计算才能知道你是否必须做新的计算。另一种方法是让影响assetAmount 的其他三个值的setter 发出willChangeValueForKeyassetAmount 并为assetAmount 设置新的原始值,然后调用didChangeValueForKeyassetAmount,并触发对自动合成的getter 的调用。我将编辑我的答案。【参考方案2】:NSArray *affectingKeys = @[@"assetAlternativeCur", @"assetAltCur", @"assetCurrency"];
告诉运行时系统这 3 个其他因素会影响 assetAmount
的值...因此,当其中一个更改时,您将收到 assetAmount
更改的通知,但其他 3 个键的设置器不会改变 assetAmount
的 getter 的工作方式.. 所以你不会得到任何改变......
您可以通过几种不同的方式强制执行此操作。您的 assetAmount
getter 可以是动态的,只需计算值然后返回即可。
或者在其他 3 个键的设置器中,您可以执行以下操作:
self.assetAmount = self.primativeAssetAmount;
但我认为这很草率,并且可能会导致问题...您应该只有一个值,然后是另一种方法,即具有格式化版本的 adjustedAssetAmount
...
一个例子是温度。
你有一个property absoluteTemp
,以及 C 和 F 的 getter。
getter for C: => absoluteTemp+273.15
getter for F: => 9/5 * absoluteTemp + 32
【讨论】:
以上是关于NSManagedObject 子类中的自定义设置器的主要内容,如果未能解决你的问题,请参考以下文章