2014-01-24 77 views
2

我想跟蹤NSManagedObject性質的變化,以保持的NSData * LASTUPDATE財產「最新」NSManagedObject的timeStamp更新

有幾種方法得到通知時NSManagedObject改變其性質

I.首先是覆蓋你想跟蹤的所有屬性的setter方法。這在NSManaged對象中非常複雜 - 請檢查它here

二。其次可能是一個好的。您可以重寫每個屬性更改時調用的「didChangeValueForKey」方法。

-(void)didChangeValueForKey:(NSString *)key{ 
    [super didChangeValueForKey:key]; 
    NSLog(@"Value for key:%@ has changed", key); 
} 

不幸的是,我們不應該重寫此方法,因爲該說的文檔...:

「你不應該重寫此方法。」

三,重要價值觀察導致我們回到IInd方法,重寫「didChangeValueForKey」。

upd。四,我試圖覆蓋-willSave方法

-(void)willSave{ 
    NSArray *observedKeys = @[@"name", @"imageType"]; 
    NSDictionary * changesALL = self.changedValues; 
    for (id key in changesALL){ 
     if ([observedKeys containsObject:key]){ 
      self.lastUpdate = [NSDate date]; 
      NSLog(@"updated For key: %@", key); 
     } 
    } 
} 

這導致了不定式循環,這在文檔中有描述。 (本書雖然是正確的做法在這裏所描述的,所以我已經回答了這個問題的話)

如果要更新一個持久的屬性值,你通常應該測試相等>與現有價值的新價值在做出改變之前。如果使用標準訪問器方法更改屬性>值,則Core Data將觀察由此產生的更改>通知,因此在保存對象的託管對象>上下文之前再次調用willSave。如果你繼續在willSave中修改一個值,willSave將繼續被調用>直到你的程序崩潰。例如,如果您設置了上次修改的時間戳,則應檢查您是否>先前將其設置爲相同的保存操作,或者現有時間戳不小於當前時間的小差值。通常,最好爲所有保存的對象計算一次timestamp(例如,響應> NSManagedObjectContextWillSaveNotification)。

+0

你想跟蹤什麼?爲什麼?這決定了相應的方法... – Wain

+0

我必須跟蹤NSManaged對象的最後更新 – KIO

回答

1

因此,畢竟我發現跟蹤Managed Object更改的最佳解決方案是註冊NSManagedObjectContextWillSaveNotification,並在託管對象上下文中的所有更新和插入對象上設置時間戳。註冊方法看起來是這樣的:

-(void)contextWillSave:(NSNotification *)notify 
{ 
NSManagedObjectContext *context = [notify object]; 
NSDate *dateOfTheLastModification = [NSDate date]; 
for (NSManagedObject *obj in [context insertedObjects]) { 
    [obj setValue:dateOfTheLastModification forKey:@"lastUpdate"]; 
} 
for (NSManagedObject *obj in [context updatedObjects]) { 
    [obj setValue:dateOfTheLastModification forKey:@"lastUpdate"]; 
} 
} 

這是假設所有的機構都有lastModifiedDate屬性,否則你必須檢查的類的對象。

3

爲您的使用情況下,以覆蓋willSave方法和使用它來設置新的lastUpdated值的合適的溶液。該方法在髒對象被保存到上下文之前被自動調用。


如果您需要確認什麼是髒的,你可以使用changedValues屬性的內容。

+0

好的,但如果我不想處理其中一個屬性會發生什麼變化呢? – KIO

+0

您可以檢查changedValues NSDictionary,並在此情況下跳過更新時間戳。 –

+0

如果你這樣做,你可能想要使用'setPrimitiveValue'方法來避免觸發另一個'willChange'調用的改變,如Apple的文檔所示:https://developer.apple.com/library/mac/Documentation/Cocoa/參考/ CoreDataFramework /班/ NSManagedObject_Class/index.html的#// apple_ref/OCC/instm/NSManagedObject/willSave –

1

爲了避免無限循環,試試這個神奇:

- (void)willSave{ 
    if(![self.changedValues objectForKey:@"localModificationDate"]){ 
     self.localModificationDate = [NSDate date]; 
    } 
    else{ 
     [super willSave]; 
    } 
} 

一旦修改日期尚未確定它不會對當前再次保存設置。有一個副作用是,如果保存失敗並且您再次保存成功,我認爲日期將來自之前的保存嘗試。

如果您在每次編輯之後保存上下文,但這樣做很好,但通常的核心數據設計只能在應用暫停或長時間保存。因此,在此之前可能會需要lastUpdate,並且它不會具有新的值。

相關問題