天后

2015-01-07 13 views
3

的X量刪除核心數據所以我有一大堆的核心數據對象和他們想要的汽車後的X日刪除(這將是基於關閉一個NSDate的)。我做了一些搜索,似乎你一次只能刪除一個核心數據對象,而不是一羣核心數據對象,更不用說基於特定日期的核心數據對象。我想也許有一個循環遍歷每個對象 - 但是這看起來像是處理器很重。關於我應該在哪裏尋找的任何想法?謝謝。天后

+0

可能重複[CoreData刪除多個對象(http://stackoverflow.com/questions/14560900/coredata-delete-multiple-objects) – tkanzakic

+0

@tkanzakic這是不是一個重複的,他知道如何刪除循環中的多個對象。他特別要求如果這樣做會令人無法接受的速度變慢,並使應用完全無法響應。 –

+0

您是否看過iOS 8中Core Data的新批量更新功能?它可以讓你更快地完成這樣的性能密集型操作。 – Abizern

回答

2

循環刪除對象一個接一個是正確的方法。在覈心數據

刪除對象是非常重的處理器。如果這是一個問題,那麼核心數據不適合你的項目,你應該使用別的東西。我建議FCModel,作爲一個非常有效的輕量級選擇。

如果你要堅持使用核心數據,這是對一個背景NSOperationQueue進行大的操作是一個好主意,所以主要的應用程序不被鎖定了,而刪除的對象。您需要非常小心Core Data跨多個線程,方法是爲每個線程分別創建一個單獨的託管對象上下文,兩者都使用相同的持久存儲協調器。不要在線程間共享一個託管對象,但可以共享對象ID,以便在另一個託管對象上下文中獲取同一數據庫記錄的第二個副本。

基本上你的後臺線程創建一個新的背景下,刪除所有的對象在一個循環,然後(最好是在主線程,見文檔)保存在後臺線程上下文。這會合並你的改變,除非有衝突(兩個上下文都修改同一個對象) - 在這種情況下,你有幾個選擇,我只是放棄整個刪除操作,然後重新開始。

蘋果擁有可用於所有的問題,並提供示例代碼這裏良好的文檔:https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdConcurrency.html

這是一個有點嚇人,你需要做一些認真的功課,但實際代碼非常簡單,一旦你有你回頭看看一切如何運作。或者只是使用專爲快速批量操作而設計的FCModel。

+2

FCModel是SQL數據庫的一種替代方案。核心數據不是數據庫;它是一個對象關係圖,它可以選擇將其數據保存在SQLite數據庫中。 – Abizern

+0

@Abizern數據庫是「爲搜索和檢索的簡易性和速度而安排的一組數據」。核心數據是一個數據庫。另外在iOS上,SQLite是唯一的數據持久性選項,OS X上的其他兩個選項在iOS上是不允許的。二進制數據存儲和XML使用太多的RAM,可能導致磁盤崩潰,導致閃存過早失效。 –

+0

我會去FCModel,但我已經有核心數據設置和使用應用程序的人的用戶羣 - 據我所知,你不能將數據從核心數據遷移到FCModel。有人在iOS 8中提到了核心數據批量更新,這會有什麼好處嗎? (我對此有點新) – mlevi

0

它並不像你想象的:)(當然這取決於數據量)

隨意使用循環

- (void)deleteAllObjects 
{ 
NSArray *allEntities = self.managedObjectModel.entities; 
for (NSEntityDescription *entityDescription in allEntities) 
{ 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    [fetchRequest setEntity:entityDescription]; 

    fetchRequest.includesPropertyValues = NO; 
    fetchRequest.includesSubentities = NO; 

    NSError *error; 
    NSArray *items = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 

    for (NSManagedObject *managedObject in items) { 
     [self.managedObjectContext deleteObject:managedObject]; 
    } 

    if (![self.managedObjectContext save:&error]) { 
     NSLog(@"Error occurred"); 
    } 
} 
} 
+0

這是處理器很重。我編寫的應用程序可能需要5分鐘才能執行'for {delete}'循環。 FCModel中的相同操作需要約0.5秒。 –

+0

是的,FCModel當然是更好的apporach,但有些只是想使用核心數據 – sztembi

+0

你知道我會怎麼做日期檢查 - 看看它是否比某個日期更早? – mlevi

0

正如其他人所指出的,迭代的對象是處理器重要真正刪除Core Data中的對象的唯一方法。這是Core Data的方法跌倒的那些用例之一,因爲它沒有針對這種用途進行優化。

但有辦法對付它,以避免在您的應用程序不需要的延遲,從而使用戶不必等待你的代碼一班班超過一噸的刪除請求。

如果你有很多需要刪除的對象,並且你不想等到這個過程完成,你可以首先僞造初始刪除,然後在方便時再進行實際刪除。喜歡的東西:

  1. 添加自定義布爾屬性稱爲像toBeDeletedNO默認值的實體類型。
  2. 當你有一堆要刪除的對象時,通過使用NSBatchUpdateRequest(iOS 8的新功能),在一個步驟中將toBeDeleted設置爲YES。這個類大多沒有文檔,所以看看頭文件或BNR blog post about it。您將指定屬性名稱和新屬性值,Core Data將進行大規模快速更新。
  3. 確保您的提取請求全部檢查toBeDeletedNO。現在標記爲刪除的對象即使仍然存在,但在提取時將被排除。
  4. 在稍後的某個時間點 - 稍後 - 在後臺運行一些代碼,用於提取和刪除toBeDeleted設置爲YES的對象。