我有一个问题,我该如何收听数据模型中的更改。
我有NSManagedObject电子邮件,其中包含属性进度。因此,当应用程序发送电子邮件时,我每次都会更新属性进度。
我想听数据模型,如果更改,请更新我的视图。
我补充说:
for (SAPEmail *email in _emails)
{
[self addObserver:email forKeyPath:@"progress" options:NSKeyValueObservingOptionNew context:NULL];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"progress"])
{
SAPEmail *email = object;
NSLog(@">>>>>>>>>>> progress: %@", email.progress);
}
}
但似乎它对我不起作用。
我也使用MagicalRecord。
我也试着观察上下文
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(handleDataModelChange:)
name:NSManagedObjectContextObjectsDidChangeNotification
object:myManagedObjectContext];
但是当我调试我的数据模型已经更新了10次(因为我从0 - 9更新进度),但handleDataModelChange在所有更新之后只调用了一次。但是每次更新数据模型以更新进度视图时,我都需要获得全部10次更新。
如果我使用这个
,还有一个[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managedObjectContextDidSave:) name:NSManagedObjectContextDidSaveNotification object:nil];
然后例如尝试刷新数据:
- (void)managedObjectContextDidSave:(NSNotification *)notification
{
NSLog(@">>>>>>>>>+++++");
_emails = [SAPCoreDataEmailHelper emailsWithStatus:EmailStatusInProgress];
[_theTableView reloadData];
}
+ (NSArray *)emailsWithStatus:(EmailStatus)status
{
NSPredicate *prediacte = [NSPredicate predicateWithFormat:@"status == %d", status];
NSArray *emails = [SAPEmail MR_findAllWithPredicate:prediacte];
return emails;
}
我可以看到NSLog是如何工作的,但我的应用程序是冻结的。
答案 0 :(得分:1)
更好的是,将获取的对象保存在NSFetchedResultsController
中。通过这种方式,您可以自动监视非常具体的实体,而无需过多详细地观察每个属性。
您是否有控制器实施NSFetchedResultsControllerDelegate
方法。这非常简单,使用核心数据检查Xcode模板(例如,Master-Detail Project,检查" Core Data")。
答案 1 :(得分:0)
您正在错误地设置观察者,请使用以下代码设置您的观察结果。
for (SAPEmail *email in _emails)
{
[email addObserver:self forKeyPath:@"progress" options:NSKeyValueObservingOptionNew context:NULL];
}
我还建议setting the context parameter正确触发KVO观察。
更新
如果您想观察核心数据的变化,您可以选择一些选项。我认为你并没有意识到有多种方法可以做到这一点。第一种方法是监视单个对象上单个属性的更改。这是KVO方法。如果要监听特定上下文的保存事件,则需要使用NSNotificationCenter方法。当您对多个上下文进行更改时,您需要将两者混合使用。也就是说,如果您正在观察上下文A中对象的属性,并且您在上下文B中对该对象/属性进行了更改,则需要在NSManagedObjectContextDidSaveNotification上设置NSNotificationCenter观察处理程序,以将来自上下文B的新更改合并到上下文A.从那里,当上下文合并完成后,然后触发对上下文A中的属性/对象的KVO观察。
在您的情况下,在managedOjbectContextDidSave:
方法中,您需要致电
-mergeChangesFromContextDidSaveNotification:
在上下文之间合并您的更改。我还建议使用多个上下文,而不是在SAPCoreDataEmailHelper类中保存单个上下文。当您进入多线程场景时,您将遇到具有单个上下文和多个线程的随机崩溃。