2010-05-20 65 views
1

當我期待它時,我的UI未更新。使用KVO更新由NSPredicate過濾的NSTableView

應用程序使用類似於iTunes的視圖顯示「項目」 - 左側的源列表允許您在右側過濾列表(NSTableView)。我的過濾器在檢查任何簡單字段(如名稱,字符串)時更新正確,但不適用於數組(如標籤)。我從一個對象(從名爲「tags」的NSMutableArray字段)中刪除一個標記,我期望它從列表中消失,因爲它不再匹配綁定到我的表的NSArrayController的謂詞。

ProjectBrowser.mm:

self.filter = [NSPredicate predicateWithFormat:@"%@ IN %K", 
               selectedTag, 
               @"tags"]; 

Project.mm:

[self willChangeValueForKey:@"tags"]; 
[tags removeAllObjects]; 
[self didChangeValueForKey:@"tags"]; 

我也試過,但結果是一樣的:

[[self mutableArrayValueForKey:@"tags"] removeAllObjects]; 

界面生成器設置:

  • 一個ProjectBrowser對象是XIB的文件所有者
  • 一個NSArrayController(項目控制器)具有結合到「文件的所有者」的內容數組.projects
  • 項目控制器的過濾器謂詞被綁定到「文件的所有者」 .filter
  • NSTableView的列綁定到「項目控制器」。名稱

回答

2

我發現這個在文檔(KVC Compliance - Dependent Values):

重要提示:請注意,您不能設置 依賴於對多關係。 例如,假設您有一個具有多對多關係的訂單 對象 (orderItems)與 OrderItem對象的集合,並且OrderItem對象具有價格屬性。您 可能希望Order對象具有 totalPrice屬性 取決於關係中所有OrderItem對象的價格。 您無法通過執行 keyPathsForValuesAffectingValueForKey: 並返回orderItems.price作爲totalPrice的關鍵路徑 。您必須 觀察每個 的OrderItem的對象的價格屬性的 的OrderItems收集,並通過更新 totalPrice自己在他們的價值觀 變化做出反應。

所以你不能依靠國際志願者組織的依賴或通知時,有在的keyPath一個一對多的關係。這適用於我的數組標籤,所以我添加了一些代碼來修補這個斷開的鏈接。

當我一個項目添加到 「項目」 陣:

[newProject addObserver:self forKeyPath:@"tags" options:NSKeyValueObservingOptionNew context:nil]; 

而且重要的部分:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    if ([object isKindOfClass:[CProject class]] && [keyPath isEqualToString:@"tags"]) 
    { 
     [self willChangeValueForKey:@"projects"]; 
     [self didChangeValueForKey:@"projects"]; 
    } 
} 

和清理,當我刪除一個項目:

[project removeObserver:self forKeyPath:@"tags"]; 

不知道這是否是最好的解決方案,但它會保持我的列表更新。

0

我很驚訝你的第一個代碼片段甚至編譯。它也可能不太工作像您期望的,因爲

self.property = foo; 

[個體經營的setProperty:FOO]語法糖;

無論如何,你的問題可能是你沒有觀察到tags。我不確定謂詞會自動觀察其查詢字符串中的鍵。

+0

感謝您指出語法錯誤,它發生在我嘗試提取相關代碼的過程中。我已經在上面糾正了它。 – KingRufus 2010-05-20 10:40:55

+0

我沒有觀察標籤,但謂詞似乎在需要時觀察簡單的字段。這個過濾器會在名稱發生變化時更新列表:[.. predicateWithFormat:@「%K ==%@」,@「name」,selectedName]因此,如果我沒有傳播變更通知,我解決這個問題? 使用像「project.someObject.someField」這樣的keypath進行觀察的KVO能力使我相信,這些改變應該「向上冒泡」給觀察者,而不需要鏈/路徑中每個鏈接上的粘合代碼。目前,數組在我的代碼的keypath觀察功能中打破了任何鏈。 – KingRufus 2010-05-20 10:50:14

+0

另一個猜測:可能是因爲您沒有更改標籤對象本身,謂詞正在優化您的更改。嘗試'[標籤發佈]; tags = [[NSMutableArray alloc] init];'而不是'[tags removeAllObjects]' – JeremyP 2010-05-20 16:24:46