ios - KVO 和 Core Data - 自观察托管对象
<p><p>我认为这个问题很简单也很常见,但我仍然不明白为什么它不起作用。让我暴露上下文:</p>
<p>假设我有一个不错的核心数据模型,其中包含一个名为 Document 的实体。该文档有类型、日期、编号和版本...例如,类型:<strong>D</strong>,日期:<strong>17-10-2015</strong>,编号:<strong >24</strong> 和版本 <strong>3</strong>。
本文档具有使用这四个值计算的标识符:<strong>D20151017-24-R03</strong>。</p>
<p>这样的文档会很多,我必须通过它的 Identifier 来搜索它们,而且我也会使用很多 <code>NSFetchedResultsController</code>。所以暂时的可能性就出来了。 </p>
<p>这就是我所做的。先注册观察四个相关属性:</p>
<pre><code>- (instancetype)initWithEntity:(NSEntityDescription *)entity insertIntoManagedObjectContext:(NSManagedObjectContext *)context {
self = ;
if (self) {
;
;
;
;
}
return self;
}
</code></pre>
<p>然后,在释放时注销:</p>
<pre><code>- (void)dealloc {
;
;
;
;
}
</code></pre>
<p>最后,管理通知:</p>
<pre><code>- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (context == KVODocumentIdContext) {
;
}
else {
;
}
}
</code></pre>
<p>就在这里<code>updateDocumentId</code>:</p>
<pre><code>- (void) updateDocumentId {
NSString * prefix = ;
NSString * date = ;
NSString * number = ];
NSString * version = ?@"":];
self.documentId = ;
}
</code></pre>
<p>对我来说,这应该是完美的......但是......它没有......</p>
<p>我有一个很好的:</p>
<pre><code>failed: caught "NSInternalInconsistencyException", "<MBSDocument: 0x7fd9dbb45f40> (entity: MBSDocument; id: 0x7fd9dbb3cd00 <x-coredata:///MBSDocument/tB55CB581-AEC0-4211-A78A-7C48377BACC2612> ; data:
...
An -observeValueForKeyPath:ofObject:change:context: message was received but not handled.
Key path: date
Observed object: <MBSDocument: 0x7fd9dbb45f40> (entity: MBSDocument; id: 0x7fd9dbb3cd00 <x-coredata:///MBSDocument/tB55CB581-AEC0-4211-A78A-7C48377BACC2612> ; data:
...
</code></pre>
<p>我尝试了很多方法,其中包括在 <code>observeValueForKeyPath:ofObject:change:context:</code> 中删除对 <code>super</code> 的调用,或者在 <code>init 中注册</code> 等。但没有任何效果。好吧,我们将不胜感激。</p>
<p>提前致谢。</p>
<p><strong>编辑:</strong>这是定义上下文的方式:</p>
<pre><code>static void * KVODocumentIdContext = &KVODocumentIdContext;
</code></pre>
<p><strong>编辑2:</strong>文档类继承自<code>NSManagedObject</code>。</p></p>
<br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
<p><p>第一件事:我不会覆盖 initWithEntity:</p>
<p>这是苹果官方 NSManagedObject 类 API 文档的节选:</p>
<p>“您也不鼓励重写 initWithEntity:insertIntoManagedObjectContext: 或 dealloc。更改 initWithEntity:insertIntoManagedObjectContext: 方法中的值不会被上下文注意到,如果您不小心,这些更改可能不会被保存。大多数初始化应在其中一种唤醒…方法中执行自定义。”</p>
<p>因此,您可能应该在 awakeFromInsert: 或 awakeFromFetch: 中添加这些 KVO 观察结果:(然后在 didTurnIntoFault 中删除这些观察者)您的子类的重写方法,也许您可以免除添加和删除观察者的所有这些开销,具体取决于什么会影响您的计算属性。</p>
<p>如果影响计算属性的键路径不是很多关系,那么你不妨编写你的 documentID 计算属性 getter 访问器并实现类方法 +(NSSet *)keYPathsForValiesAffectingDocumentID,它返回一个包含键路径的 NSSet,如果更改将导致使用新值重新计算计算机属性。 </p></p>
<p style="font-size: 20px;">关于ios - KVO 和 Core Data - 自观察托管对象,我们在Stack Overflow上找到一个类似的问题:
<a href="https://stackoverflow.com/questions/30975997/" rel="noreferrer noopener nofollow" style="color: red;">
https://stackoverflow.com/questions/30975997/
</a>
</p>
页:
[1]