跟踪NSManagedObject属性,当它更新并立即更新视图

问题描述:

我有一个问题,我怎么能听我的数据模型的变化。跟踪NSManagedObject属性,当它更新并立即更新视图

我有财产进步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但后来我的应用程序是冻结。

您正在设置不正确的观察者,请使用以下代码设置您的观察值。

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类中保存单个上下文。当你到达多线程场景时,你会遇到单个上下文和多个线程的随机崩溃。

+0

谢谢你回答你,每次帮我)我有单身,给我发电子邮件,在这里我使用魔法导入来设置所有属性以及进度。在视图控制器中的另一个对象中,我想观察所有的电子邮件,并且在初始化此视图控制器时,我使用SAPEmail MR_findAllWithPredicate。但我认为,当核心数据发生变化时,我在视图控制器中使用的电子邮件不知道它。因为更改发生在上下文中,而不是通过MR_findAllWithPredicate获得的对象。正确? – 2014-09-05 16:11:46

+0

仍然无法观察到 – 2014-09-05 16:49:07

+0

我也更新了问题 – 2014-09-05 16:52:47

更好的是,将您提取的对象放在NSFetchedResultsController中。通过这种方式,您可以自动监视非常特定的实体,而不用过多详细地观察每个属性。

你控制器是否执行NSFetchedResultsControllerDelegate方法。这非常简单,请使用核心数据(例如Master-Detail Project,检查“核心数据”)检查Xcode模板。