willSave 或 validateForUpdate 中的 NSManagedObject 动态属性更新
Posted
技术标签:
【中文标题】willSave 或 validateForUpdate 中的 NSManagedObject 动态属性更新【英文标题】:NSManagedObject dynamic attribute update in willSave or validateForUpdate 【发布时间】:2012-05-07 16:34:35 【问题描述】:我有一个 NSManagedObject,它有一个仅用于在 NSFetchedResultsController 中排序的属性。该属性的值由其他属性或关系的值确定。
因此,当我准备保存对象时,我会弄清楚它的价值。从我阅读文档和实验来看,我似乎可以在- (void) willSave
或- (BOOL) validateForUpdate: NSError **error
中执行此操作。
我的实验表明这些是串联调用的,首先是validateForUpdate
,然后是willSave
。
但是,由于我对幕后发生的事情的洞察力很差,我想知道是否有人可以建议一个地方是否比另一个地方更好来设置值以及为什么?
谢谢。
【问题讨论】:
【参考方案1】:如果你有一个派生值,你通常不想保存它,但如果你确实想保存它(因此否定了动态生成它的优势,但如果你有很多对象并想做一些花哨的谓词工作。)您可以在模型中将其设置为普通值,然后创建一个自定义访问器来检查是否设置了原始值,使用primitiveValueForKey:@"propertyName"
...类似
.h
@property()NSString* someProperty;
.m
@dynamic someProperty;
-(NSString *) someProperty
pValue = [self primitiveValueForKey;@"someProperty"];
if(!pValue)
//calculate pvalue
pValue = [self derivedPValue];
[self setPrimitiveValue: pValue forKey:@"someProperty"];
return pValue;
【讨论】:
谢谢格雷迪。我完全同意并且不想存储它。我试图让一个瞬态属性工作,但我无法让排序工作,因为该值不在 SQL 存储中,并且排序似乎是在 SQLite 中完成的。 如果您不想存储它,那么只需定义一个 getter,并在其中导出值,您的所有 kv 代码都应该可以正常工作,但您将无法从数据库... 这就是我的想法,但是使用像[NSSortDescriptor sortDescriptorWithKey: @"sortPosition" ascending: NO]
这样的排序描述符设置我的排序描述符数组时,我因为未捕获的异常而崩溃,原因是:'keypath sortPosition not found in entity TravelSegment
是 Xcode 自动生成的 NSManagedObject
的子类,并在一个类别中将 sortPosition
定义为 @property (nonatomic, readonly) NSInteger sortPosition;
并使用适当的方法返回 NSInteger。跨度>
好的,我尝试了这个并遇到了以下问题:实体数据在持久存储中按顺序获取(因为似乎排序描述符已转换并应用于 SQL SELECT 语句)但是节标题是从对象属性生成的。使用此自定义 getter,属性值可能最终与数据库中的值不同,并且对象最终位于错误的部分 - 崩溃并显示消息 在索引 2776 处获取的对象的部分名称无序【参考方案2】:
你可能想加入willSave
;从技术上讲,您并没有进行验证,discussion for the method 引用了计算派生值。
【讨论】:
这是有道理的。如果我对对象进行了更改但不保存NSManagedObjectContext
,是否有可能通过使用willSave
,我的派生值不会得到更新并且我的显示可能与当前值不同步?
是的,当然。您最好使用上面@GradyPlayer 建议的派生属性方法。以上是关于willSave 或 validateForUpdate 中的 NSManagedObject 动态属性更新的主要内容,如果未能解决你的问题,请参考以下文章
即使没有保存上下文,NSFetchedResultsController 委托也会触发