1

我有一些數據由2個表的記錄組成:對和項目。這些表格與多對多關係相關聯。我看到兩種可能的方式來填補核心數據實體。讓我們已經填滿了所有的項目,現在我們應該填補對。在這兩種情況下,「標識符」都是附加的文本屬性/字段。核心數據。 NSDictionary VS NSFetchRequest?

路1(NSFetchRequest只):

//get data which should be converted to core data entities 
id pairsInfoArray = ...; 
for (id pairInfo in pairsInfoArray) { 

    //get items by identifier using NSFetchRequest 
    id item1 = ...; 
    id item2 = ...; 
    //create pair entity 
    id pair = ...; 
    pair.items = [NSSet setWithObjects:item1, item2, nil]; 
} 

路2(僅一次調用NSFetchRequest和使用的NSDictionary /的NSMutableDictionary代替):

//get all items via NSFetchRequest 
NSArray *itemsObjArray = ...; 
//place all the items into array as key = item.identifier, value = item (as object) 
NSMutableDictionary *itemsObjDict = ...; 
//get data which should be converted to core data entities 
id pairsInfoArray = ...; 
for (id pairInfo in pairsInfoArray) { 

    //get items by key from itemsObjDict 
    id item1 = ...; 
    id item2 = ...; 
    //create pair entity 
    id pair = ...; 
    pair.items = [NSSet setWithObjects:item1, item2, nil]; 
} 

我所有的數據(不僅是項目,對)在5分鐘(路1)和45秒(路2)中填滿。它包括執行[context save:nil]的時間。

當我看到第二個工作方式比第一種快得多。但是它有什麼隱藏的缺點?例如不會將項目保存到額外的字典會浪費內存?

回答

1

你不顯示如何保存 - 這可以產生相當大的效果。

選項1具有記憶效率但不具時間效率。

選項2時有效,但不是記憶效率(你試圖通過儀器運行它/舊的設備上?)。

你應該想想,你運行一個混合解決方案(並保存)批次。通過試驗和分析來設置批量大小。儀器有一些核心數據工具來幫助解決這個問題。您的目標是儘可能少地利用最少的內存使用量,最少的提取次數和最少的上下文保存次數。

+0

所有項目都存儲在上下文中(除了此部分數據與way2,他們另外存儲在數組和字典中)。在填充數據庫之前創建上下文,並在所有數據成功解析時調用save:。但是如果上下文浪費了大量的內存,那麼這會浪費兩種情況下的內存。 – user2083364

+1

上下文不浪費內存,當您獲取對象時使用內存。所以當你讀取一個數組(這是選項2)時,你的內存使用率很高。 – Wain

+0

謝謝你的回答。最後一個問題是如果我將手動釋放數組以防止在方式2結束時浪費內存而不是autorelease數組? – user2083364

1

當然有一個很大的缺點。

你持有的所有數據存儲在存儲器例如2.當然,這始終是最快的方式,但不是最好的移動設備。

CoreData是一個對象圖,而不是一個存儲存儲。默認情況下,它不會立即使用內存來創建對象。它在你真正開始使用它時創建對象,意味着使用這些屬性。在它只是持有一個小的參考 - 所謂的故障。 CoreData平衡內存與性能,並允許您控制加載到內存中的數據和時間。從獲取中獲取的NSArray實際上只有少量內存已準備好。當您訪問該元素時,其餘部分將變爲真實。我們通常沒有任何時候需要所有對象的情況。通常我們的Collectionviews只顯示一些對象的一些信息,但從來沒有。當然,您可以簡單地獲取所有對象並告訴他實際加載對象。那麼他將會像例子二一樣快。也許在某些情況下速度更快,因爲NSSet在相交等方面擁有驚人的能力。

有幾個很好的WWDC研討會展示瞭如何處理這個問題。一般情況下,CoreData總是最好的解決方案,除非我們談論的是僅僅在內存中花費幾千字節並且不會造成任何傷害的微不足道的數據。但是你的時間數字表明你有很多數據。並非所有數據都是必需的。拆分它,創建一個實體,以保存需要顯示的必要信息,並將其餘部分放入其他實體中。當你需要詳細信息時,你可以訪問額外的實體,並在一小段延遲後獲得對象。(稱爲延遲加載)

請在Core數據中嘗試我的建議,並查看設備運行時與使用NSDictionary解決方案時使用的內存量。我想你會看到不同之處。

+0

我使用NSSet是因爲一個簡單的原因:所有的鏈接都有反向鏈接。如果你有兩個有多對多關係的字段被引用到同一個表格(第二個表格只允許設置一個反向鏈接),那麼做到這一點是可行的。 感謝您的建議,我會在稍後看到內存。 項目另外有兩個雙參數和其他參數鏈接到其他設施。我檢查了一下,我發現大部分時間都花在創建一對和兩個項目之間的鏈接上。我甚至試圖優化這個過程,但總時間不少於3分鐘。 – user2083364

+0

我目前的解決方案是方式3,但它打破了核心數據結構。這意味着類別不與項目鏈接並僅包含其標識符。 最後一個問題是如果我將手動釋放一個數組以防止在方式2結束時浪費內存? – user2083364

相關問題