2010-08-27 117 views
0

我有一組數據由另一個應用程序創建並以XML格式存儲在磁盤上。由於這個數據是由這個其他應用程序管理的,我不想費心將這些數據加載到Core Data存儲中,原因有兩個:1)它會冗餘存儲相同的數據,2)我必須不斷地更新我自己的Core Data存儲以匹配其他應用程序生成的XML文件中的更新。通過來自非核心數據對象的綁定訪問核心數據對象的屬性

但是,我在自己的應用程序中創建的數據需要與來自其他應用程序的XML數據相關聯,並且我想將自己的應用程序中創建的數據保存到磁盤。

要完成此操作,來自其他應用程序的XML數據具有與存儲在XML文件中的每個對象關聯的持久唯一ID。我將這些唯一的ID存儲在我自己的Core Data存儲中。在每次啓動我的應用程序時,我都會加載由其他應用程序創建的XML數據,然後通過發佈對與唯一ID匹配的託管對象的提取請求,可以通過Core Data在我自己的應用程序中訪問相應的數據。

OtherAppObjects表示從XML數據加載的項目。除了uniqueID以外,他們還擁有自己獨特的屬性。這些OtherAppObjects由一個NSArrayController控制。然後我有從Core Data存儲中加載的MyManagedObjects,並且除uniqueID外還具有不同的唯一屬性。

我有一個表視圖,需要顯示來自OtherAppObjects以及MyManagedObjects的屬性,所以我希望能夠通過來自OtherAppObjects的綁定來訪問和設置MyManagedObjects的屬性。因此,我想我可以創建OtherAppObjects的相應MyManagedObject屬性,然後我可以通過綁定訪問MyManagedObject的Core Data屬性。例如,如果我想要在表視圖中顯示OtherAppObjects的屬性「foo」和MyManagedObjects的「bar」,我可以簡單地將一個表列與NSArrayController綁定,其中模型關鍵字路徑爲「foo 「,並將第二個表列綁定到」correspondingMyManagedObject.bar「的模型鍵路徑。

這適用於不處理多個線程或傳遞單個託管對象上下文時。但是,由於這是「強烈不鼓勵」,我想通過傳遞一個持久性存儲協調器來嘗試以正確的方式做到這一點,但創建單獨的託管對象上下文。

但是,這個失敗了。問題是當表視圖試圖訪問bar屬性時,它需要首先訪問相應的MyManagedObject屬性。因此,OtherAppObject忠實地創建一個新的託管對象上下文和一個相應的獲取請求,並帶有適當的uniqueID並返回託管對象。但是這樣做會釋放託管對象上下文,現在託管對象不再有效,因此表視圖無法訪問bar屬性!

我只看到兩個解決這個辦法,我想確認沒有做到這一點的另一個更簡單的方法:

  1. 負載從XML數據的對象到我自己的核心數據存儲。本質上,從OtherAppObjects中創建ManagedOtherAppObjects,並與MyManagedObjects建立關係,然後通過綁定進行訪問將非常實用。但是,這意味着在磁盤上有相同數據的冗餘存儲,每次啓動應用程序時(因爲XML文件更新頻率相當高),我將不得不重新創建ManagedOtherAppObjects。

  2. 在OtherAppObject類上創建自定義setter/getters。因此,例如,我會在OtherAppObject中創建-(NSValue *)bar-(void)setBar:(NSValue *)newValue方法。然後,我不是將表視圖列綁定到OtherAppObjects的鍵值路徑「correspondingMyManagedObject.bar」,而是將它綁定到OtherAppObjects的關鍵路徑「bar」。這些方法將能夠獲取相應的MyManagedObject和檢索或內管理對象範圍內設置的值,然後返回正確的值。

該第二方法沒有特別吸引人的,因爲我不得不創建MyManagedObject的每一個屬性(其他管理對象進行MyManagedObject有關係的特性)兩個自定義的方法。

我想我可以創建廣義方法-(NSValue *)retrieveCoreDataPropertyUsingKeyPath:(NSString *)keyPath-(void)setCoreDataProperty:(NSValue *)newValue usingKeyPath:(NSString *)keyPath,但我仍然必須爲每個單獨的屬性創建shell setter/getters。

[更新:嗯,也許我可以只覆蓋valueForKeyPath:setValue:forKeyPath:,然後就不會有什麼問題OK?]

這是正確的,還是我失去了一些東西?在選項#1

回答

0

一個變化,可能是值得一試。將設置的東西,讓你有一個持久存儲協調其將兩個單獨的持久性存儲的對象。你可以保持MyManagedObjects(MMO)相同,單獨存儲在磁盤上,但是OtherAppObjects(OAO)可以通過臨時存儲在磁盤上(例如在〜/ Library/Caches或其他)內存存儲。

一經推出,您將創建您的PSC和添加包含大型多人在線遊戲商店。然後,您可以添加第二個店的PSC(使用-[NSPersistentStoreCoordinator addPersistentStoreWithType:configuration:URL:options:error:]),在XML文件中讀取和創建所有OAOs,並使用-[NSManagedObjectContext assignObject:toPersistentStore:]那家商店的那些對象相關聯。

核心數據不允許在不同的商店對象之間的直接建模的關係,但是就像你現在在做與OAO一款MMO關聯,你可以仍然可以通過唯一的ID做查找。區別在於OAO可以簡單地使用自己的託管對象上下文來獲取MMO,因此您可以確信MMO至少會像OAO一樣長。

然後,當您退出應用程序時,您可以刪除〜/ Library/Caches中的臨時存儲,或者如果使用內存存儲,只需讓它消失到以太網中, MMO完好無損。

+0

這是一個有趣的想法。我試着實現它。它的工作原理與廣告一樣,有一個非常大的缺點:性能是不可接受的。 保持對不同商店中託管對象的引用的唯一方法似乎是通過提取請求。所以現在,當我想通過OAO(它們本身就是管理對象)訪問MMO的屬性時,我會通過OAO的「對應的MyManagedObject」屬性,這只是一個獲取請求。產生數以千計的這些取從表視圖結果的請求在等待兩分鐘,應用程序啓動時,當它是先前2秒 – 2010-09-01 04:14:47

+0

嗯,發生,我認爲我可以通過的objectID存儲對對象的引用,而不是需要一個取指令請求。 ..這個想法可能還有效。 – 2010-09-01 04:54:14

+0

如果確實使用objectID,請注意臨時ID,並確保只保存永久ID。 – 2010-09-02 04:39:43