【发布时间】:2011-12-28 22:28:30
【问题描述】:
我有一个NSManagedObject 有两个属性:
NSNumber *score;
NSDate *score_timestamp;
我希望每次更新 score 时都更新我的 score_timestamp 字段。
我显然不能使用-willSave 方法,因为我的上下文偶尔会被保存,而score_timestamp 不会是最新的。所以我应该覆盖-setScore: 或者将我的托管对象设置为它自己的score 字段的键值观察器。
-setScore: 的解决方案似乎很简单:
- (void) setScore:(NSNumber *)score
{
[self willChangeValueForKey:@"score"];
[self setPrimitiveScore:score];
[self didChangeValueForKey:@"score"];
self.score_timestamp = [NSDate date];
}
以这种方式做事有什么注意事项吗?还是我应该使用 KVO 解决方案?
更新
到目前为止,我收到了两个回复,我的代码无法通过 setValue: forKey: 运行,我仍在等待例如。天真地调用[(NSManagedObject *)myObject setValue:value forKey:@"score"] 调用我的设置器都是一样的。
所以如果我切换到 KVO 解决方案,我是否应该在所有 awake 方法中 addObserver: 并在 willTurnIntoFault 中删除它?还是没那么简单?
【问题讨论】:
-
说真的,两个回答者都说 setValue... 不起作用是错误的。您可以通过在访问器中放置一个断点,然后使用 setValue 更改值来非常简单地进行测试。
-
@jrturton 我已经测试过了,它肯定会被调用。但我不是核心数据专家,无法确定是否有另一种方法可以在没有访问器的情况下更改我的属性。我的意思是在实际代码中偶尔使用的方式。
-
不。所有核心数据调用都将通过您的设置器(可能首先通过 setValueForKey)。这是封装原则的一部分。您可以对 ivar 进行一些怪异的直接访问,但这必须是您自己编写的,这可能也会破坏托管对象上下文。你不会这样对自己,对吗?
-
@jrturton 是的,这是一个很好的解释!我从一开始就是这么想的(否则我会立即从 KVO 开始),但是你看,有些人说这不正确 :) 如果你创建一个答案让我标记它会很棒。
-
@jrturton 抱歉,我好像注意力不集中,我肯定需要睡觉了。我刚刚发现我在你的合法答案中添加了一个警告(错过了你编辑它的那一刻),所以我删除了我的笔记。让我们按照以下方式来做吧:我现在不能相信自己做出决定,所以明天早上我会回到我的问题 :) 谢谢你的帮助!
标签: objective-c core-data nsmanagedobject key-value-observing