簡體   English   中英

模型間/ NSManagedObject通信

[英]Inter-Model/NSManagedObject communication

我有兩個NSManagedObject子類:Parent和Child。 Parent在OrderedSet中包含許多Child(ren)。 當孩子的狀態發生變化時,我希望父母知道它。

如果我使用其他語言進行編程,我可能會使用事件,讓父母監聽來自每個孩子的事件,但是鑒於目標操作僅限於查看組件,所有Objective C都提供給我使用全局NSNotificationCenter。 我絕對不喜歡使用模型進入全局通知的想法(直接通過事件直接監聽我的書中的確定),所以看來我唯一的選擇是委托。 然而,在兩個NSManagedObjects之間使用委托似乎是一個危險的想法,因為很難確保一方不會丟失對另一方的引用。

有沒有人對我應該如何處理這個有任何建議?

另一種選擇是鍵值觀察。 設置如下:

const static void *kParentObservingChildSomePropertyContext = &kParentObservingChildSomePropertyContext;

[child addObserver: child.parent forKeyPath: @"someProperty" options: /*see below*/ context: kParentObservingChildSomePropertyContext];

存在奇怪的常量定義,因為每個觀察上下文都應該是唯一的,這樣你就不會踩到超類或子類觀察上下文。 要查看需要設置的選項, 請參閱手冊並與您的具體需求進行比較。 現在,只要您的子對象上的該屬性發生更改,您的父級將會收到:

-(void)observeValueForKeyPath: (NSString *)path ofObject: (id)object change: (NSDictionary *)change context: (void *)context;

檢查您是否具有正確觀察背景,然后處理更改。 如果您在此處獲得不同的上下文,請將消息轉發給super

當您完成觀察路徑時,您將父項刪除為子項的觀察者:

[child removeObserver: child.parent forKeyPath: @"someProperty" context: kParentObservingChildSomePropertyContext];

使用在-addObserver:forKeyPath:options:context使用的相同上下文指針-addObserver:forKeyPath:options:context以便刪除正確的觀察實例。

然而,在兩個NSManagedObjects之間使用委托似乎是一個危險的想法,因為很難確保一方不會丟失對另一方的引用。

委派,觀察和觀察來自特定對象的通知都會遇到這個問題。 您需要確保您對通知感興趣的生命周期與所涉及對象的生命周期相匹配,否則您可能很容易“泄漏”觀察信息或 - 這更糟糕 - 將通知發送到過時的對象指針。 這些解決方案都不具備這一點,但在Delegate模式的情況下,您可以使用歸零弱引用來確保當父對象消失時,子進程將不再嘗試委托它。

我在視圖控制器中選擇一個字段來監視請求... [self addObserver:self forKeyPath:@“clientProgress.dateLastUpdated”options:0 context:nil];

我確保在相同的視圖控制器中刪除dealloc上的觀察者(或者在ARC中的dealloc的任何傳遞)。 - (void)dealloc {[self removeObserver:self forKeyPath:@“clientProgress.dateLastUpdated”]; }

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqual:@"clientProgress.dateLastUpdated"]) {
    // If this key path has changed, the browser needs to update its display.
    NSError *error = nil;
    if (![managedObjectContext save:&error]) {
        UIAlertView *dialog = [[UIAlertView alloc] initWithTitle:@"Save Error" message:@"Error saving inserted record, contact Tech Support" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
        [dialog show];
        [dialog release];
        exit(-1);  // Fail
    }
    if ( changeIsComingFromLibraryInsert ) {

    }
    [conditioningTableView reloadData];
}
// Essential to call super class implementation - NSArrayController relies heavily on KVO
//[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];

}

最后,當我想調用觀察者時,我只是更新日期... //通過設置修改日期和前面的ViewController強制保存,然后從調用視圖控制器保存並重新加載//因為有一個觀察者正在運行看這個關鍵值clientProgress.dateLastUpdated = [NSDate date];

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM