Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Cocoa NSManagedObject子类中的自定义Setter_Cocoa_Core Data_Key Value Observing - Fatal编程技术网

Cocoa NSManagedObject子类中的自定义Setter

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"]) {

我的NSMAnagedObject中有一个实体依赖于其他实体,因此在阅读了上的文档后,我在我的子类中提出了以下内容

+ (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的调用。我将编辑我的答案。