2017-01-12 54 views
0

任何人都可以提出一個很好的模式來實現Realm對象上的髒標誌嗎?具體來說,我希望Realm Object的每個子類都公開一個isDirty標誌,該標誌在類的實例被修改時得到設置,並在實例寫入雲(而不是Realm)時清除。我正在Objective-C中工作。Realm對象上的髒標誌

可能的解決方案,我能想到的包括以下內容:

  • 寫定製的setter爲每個對象的每個屬性。在每個設置者中設置isDirty。不是很理想。
  • 以某種方式使用KVO。這種方法存在兩個問題:(a)我不完全理解如何實現這種方法,以及(b)Realm不支持託管對象的KVO(這正是我需要的對象)。
  • 使用領域通知。再次,我沒有這些經驗,我不確定如何將它們用於此目的。

回答

0

簡而言之,您在執行每個寫入事務後手動設置的非管理isDirty屬性,KVO將是最佳途徑。

設置自定義設置器確實會令人難以置信的混亂。您必須爲每個您想要跟蹤的房產分別安裝一個。

如果您正在跟蹤一組對象並希望在有任何更改(使用collection notifications)或if anything in the Realm changed時想要收到警報,則領域通知將僅適用。

使用KVO,您可能會得到您的對象子類本身,以便將觀察者添加到其所有屬性中,然後在任何一個方法發生更改時將其引導到一個方法,然後可以將其用於標記isDirty屬性。

@interface MyObject: RLMObject 

@property NSString *name; 
@property NSInteger age; 

@property BOOL isDirty; 

- (void)startObserving; 
- (void)stopObserving; 

@end 

@implementation MyObject 

- (void)startObserving 
{ 
    NSArray *properties = self.objectSchema.properties; 
    for (RLMProperty *property in properties) { 
     [self addObserver:self forKeyPath:property.name options:NSKeyValueObservingOptionNew context:nil]; 
    } 
} 

- (void)stopObserving 
{ 
    NSArray *properties = self.objectSchema.properties; 
    for (RLMProperty *property in properties) { 
     [self removeObserver:self forKeyPath:property.name]; 
    } 
} 

- (void)observeValueForKeyPath:(NSString *)keyPath 
         ofObject:(id)object 
         change:(NSDictionary<NSKeyValueChangeKey,id> *)change 
         context:(void *)context 
{ 
    self.isDirty = YES; 
} 

+ (NSArray *)ignoredProperties { 
    return @[@"isDirty"]; 
} 

@end 

顯然,你會想在這裏比我做做更多的檢查(確保isDirty真正需要設置),但是這應該給你一個想法。

沒有真正的方法可以自動知道何時創建了託管的Realm對象,因此最好在您需要時手動啓動和停止觀察。

+0

感謝您的回覆。我們確實嘗試過這樣的事情,並且在我們創建最終由Realm管理的對象的情況下,它工作正常。但是,如何在Realm中從**中檢索對象時自動安裝觀察器。看來,Realm並不總是/永遠不會調用我們的類的「init」方法。所以我們不能以這種方式安裝觀察者。有什麼方法可以讓應用程序攔截Realm'init'方法,以便它可以自動安裝觀察者? –

+0

不用擔心!是的,這就是我最後提到的。被管對象由不同的私有API實例化,所以'init'不會被調用。因此,目前,只需簡單地覆蓋內部API,最簡單的解決方案就是在您希望開始觀察時手動調用。 – TiM

+0

如果您認爲Realm第一次創建對象時應該調用方法,我鼓勵在http://github.com/realm/realm-cocoa/issues提出它。 – TiM