0

我有一個問題,我怎麼能聽我的數據模型的變化。跟蹤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但後來我的應用程序是凍結。

回答

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類中保存單個上下文。當你到達多線程場景時,你會遇到單個上下文和多個線程的隨機崩潰。

+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

1

更好的是,將您提取的對象放在NSFetchedResultsController中。通過這種方式,您可以自動監視非常特定的實體,而不用過多詳細地觀察每個屬性。

你控制器是否執行NSFetchedResultsControllerDelegate方法。這非常簡單,請使用核心數據(例如Master-Detail Project,檢查「核心數據」)檢查Xcode模板。