2014-12-30 40 views
5

我嘗試的第一件事是使用FetchedResultsController來解決我的問題。這是一個非典型的使用FRC的,我沒有更新的TableView,我用它只是爲了確定是否實體正在發生變化,所以我知道什麼時候保存到服務器:如何在CoreData中偵聽特定的實體保存/更新

self.fetchedResultsController = [Document MR_fetchAllSortedBy:@"timestamp" 
                ascending:NO 
               withPredicate:[NSPredicate predicateWithFormat:@"report.remoteId != nil && dirty == YES"] 
                 groupBy:nil 
                delegate:self 
                inContext:_managedObjectContext]; 

這裏的問題是,FRC在關係實體更改時不會收到更新。 IE如果report.remoteId從零變爲非零我不會看到更新,因爲FRC僅監聽文檔實體上的更改。這裏列出的限制:http://www.mlsite.net/blog/?p=825和這裏Changing a managed object property doesn't trigger NSFetchedResultsController to update the table view

不知道我真的想實施解決方法,因爲我倒下了,就像我使用FRC的東西,它不是爲了做的事情。我不認爲蘋果會解決這個限制,所以我並不是真的想把一個圓形釘子打成方形洞來解決我的問題。

幾個選項

消防代碼的通知後,我已保存的實體,然後聽一聽是其他地方。唯一我不喜歡的事情是,程序員要做到這一點並保持最新狀態,也就是說,如果有人出現並將實體保存在另一個地方,他們必須記得發出通​​知。

偵聽保存到默認MOC。這是我真正想做的事情。類似這樣的:

[[NSNotificationCenter defaultCenter] 
     addObserver:self 
     selector:@selector(handleDataModelChange:) 
      name:NSManagedObjectContextObjectsDidChangeNotification 
      object:[NSManagedObjectContext MR_defaultContext]]; 

- (void)handleDataModelChange:(NSNotification *)note { 
    NSSet *updatedObjects = [[note userInfo] objectForKey:NSUpdatedObjectsKey]; 
    NSSet *deletedObjects = [[note userInfo] objectForKey:NSDeletedObjectsKey]; 
    NSSet *insertedObjects = [[note userInfo] objectForKey:NSInsertedObjectsKey]; 

    // Do something in response to this 
} 

這是我的兩難。這將監聽默認MOC上的所有更改。我真的只關心一些實體的變化。所以是的,我可以在每次通話中篩選出我關心的實體。但是,我有一個案例,我拯救了大量我不關心的其他實體。這意味着NSManagedObjectContextObjectsDidChangeNotification會觸發很多時間,大部分時間我都不在乎。我不想通過不斷收到此通知並花時間篩選出我不關心的所有實體來減慢我的應用程序速度。

有沒有辦法監聽特定的實體保存?無論是在CoreData,還是MagicalRecord?

如果答案是否定的,是有聽更改特定實體(及其關係)一個很好的選擇?

回答

9

有沒有辦法聽的變化一組特定的實體;捕捉NSManagedObjectContextObjectsDidChangeNotification(或已經或將要保存)並且過濾是正確的方法,但要注意的是,如果您正在討論實體的特定實例,則鍵值觀察也是一種選擇。

但是,值得注意的是NSManagedObjectID是線程安全的併爲NSEntityDescription提供了一個getter。所以你可以

- (void)handleDataModelChange:(NSNotification *)note { 
    NSSet *updatedObjects = [[note userInfo] objectForKey:NSUpdatedObjectsKey]; 
    NSSet *deletedObjects = [[note userInfo] objectForKey:NSDeletedObjectsKey]; 
    NSSet *insertedObjects = [[note userInfo] objectForKey:NSInsertedObjectsKey]; 

    NSMutableArray *objectIDs = [NSMutableArray array]; 
    [objectIDs addObjectsFromArray:[updatedObjects.allObjects valueForKey:@"objectID"]]; 
    [objectIDs addObjectsFromArray:[deletedObjects.allObjects valueForKey:@"objectID"]]; 
    [objectIDs addObjectsFromArray:[insertedObjects.allObjects valueForKey:@"objectID"]]; 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(){ 
     NSSet *affectedEntities = [NSSet setWithArray:[objectIDs valueForKeyPath:@"entity.name"]]; 

     if([affectedEntities containsObject:@"InterestingEntity"]) { 
      // get back onto the main thread and do some proper work; 
      // possibly having collated the relevant object IDs here 
      // first — whatever is appropriate 
     } 
    }); 
} 
+0

謝謝@Tommy!比覆蓋NSManagedObject的onSave方法更好/更糟? – lostintranslation

+0

取決於您的使用情況。如果您試圖捕獲實體Q的所有實例的保存,並且您一次保存1000個實例(可能來自Web服務或某處),那麼您將只獲得一個通知,但只有1,000個'didSave'。我想問題在於你是否希望讓這些對象獨立行事(例如,應用自動更正驗證),或者你正在以某人的角度來看待這些對象(例如,你有一個大而複雜的視圖可以做一些事情基於數據的總體而不是僅顯示每個數據)。 – Tommy

+0

......我可能唯一難以理解的是,在表格視圖這樣的關鍵值觀察中,由於添加和刪除觀察者的成本而快速滾動時會產生意想不到的成本,大概是因爲從0觀察者到1和副作用反之亦然是一種調整方法,突變消息傳遞圖和某種內部到KVO實例圖。在這種情況下,我發現捕獲通知,處理和推送主隊列變化的阻塞列表是一個更好的解決方案。 – Tommy

2

通過閱讀文檔和其他一些形式後,我也想出了另一種可能的解決方案。

爲什麼不覆蓋 - (無效)didSave管理對象的方法,以捕獲對象上的變化。

@implementation Report (helper) 

- (void) didSave { 
    [super didSave]; 

    // if not on default context no-op 
    if ([NSManagedObjectContext MR_defaultContext] != self.managedObjectContext) return; 

    // send custom notification here 
} 

@end 

與發送自定義通知還是交易,但在管理對象至少在封裝,使得開發者不必擔心在哪裏發送通知。

從好的一面來看,這隻對我關心的被管理對象執行。

減號是它被調用所有託管對象上下文。不過,我不認爲MOC支票會是一個沉重的打擊者。

不知道這是否比在默認MOC上進行保存和過濾時收聽更好/更差。此外,在這種情況下,我知道我只在該MOC上收聽節目。儘管我可以過濾後臺任務,但我仍然在過濾大量的數據,這種情況下我不需要處理。

想法?

+0

註冊到'NSManagedObjectContextDidSaveNotification'。 –

相關問題