2012-01-07 91 views
2

我正在對應用程序進行收尾處理,並且在批量刪除記錄時遇到困難。在一個按鈕的點擊一組約。需要將3500條記錄添加到數據庫中。這不是問題,需要大約。 3-4秒。刪除/刪除核心數據中的記錄非常非常慢

但有時(不經常,但選項需要在那裏)所有這些記錄需要刪除。我剛剛執行了這個操作,花了20分鐘。這裏有什麼可能是錯的?只有一個依賴關係,所有記錄都是特定集合的子集。

我將所有項目添加到一個集合中,將它們從集合中刪除,然後逐個刪除。每5%我更新一次對話,當一切完成時,我會提交更改。但在取出物品只需要在年齡DOItemController(我可以看到進度對話的進展非常緩慢)

- (void) deleteList:(DOCollection *) collection { 

    // For the progress dialogue 
    NSMutableDictionary* dict = [NSMutableDictionary dictionaryWithObject:@"Clearing vocabulary list!" forKey:@"message"]; 
    float totalItems = [collection.items count]; 
    float progress = 0; 
    float nextProgressRefresh = 0.05;   

    NSMutableSet* itemsSet = [NSMutableSet set]; 
    for (DOItem* item in collection.items) { 
     [itemsSet addObject:(NSNumber*)[NSNumber numberWithInt:[item.itemId intValue]]]; 
    } 

    // Remove all of them from the collection 
    [managedObjectContext performBlockAndWait:^{ 
     [collection setItems:[NSSet set]]; 
    }];  

    for (NSNumber* itemId in itemsSet) { 
     DOItem* item = [itemController findItem:[itemId intValue]]; 
     if (item != nil) { 
      [[self itemController] removeItem:item]; 
     } 

     progress++; 
     if((nextProgressRefresh < (progress/totalItems))){ 
      NSString* sProgress = [NSString stringWithFormat:@"%f", (progress/totalItems) * 0.85]; 
      //[dict setValue:@"Saving the database...!" forKey:@"message"]; 
      [dict setValue:sProgress forKey:@"progress"]; 
      [[NSNotificationCenter defaultCenter] postNotificationName:kUpdatePleaseWaitDialogue object:dict]; 
      nextProgressRefresh = nextProgressRefresh + 0.05; 
     }   
    } 

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     [managedObjectContext performBlockAndWait:^{ 
      [[self collectionController] commitChanges]; 
     }]; 
     [[NSNotificationCenter defaultCenter] postNotificationName:kSavingDataComplete object:nil]; 
    }); 

    //NSLog(@"Wait 2!"); 
    [NSThread sleepForTimeInterval:1];  

} 

- (void) removeItem: (NSManagedObject*) item { 
    [[self managedObjectContext] deleteObject:item]; 
} 
+0

DOCollection是一個託管對象嗎?或者不僅僅是一組管理對象? – timthetoolman 2012-01-07 21:27:06

+0

是的都是管理對象 – 2012-01-08 07:44:04

+0

你有核心數據模型中級聯刪除的設置嗎? – timthetoolman 2012-01-08 08:30:35

回答

2

不知道你是如何架構的數據模型。但我會設置它級聯刪除你的對象。如果DOItem對象對於DOCollection是唯一的,則可以將刪除規則設置爲級聯。這將自動刪除相關的DOItem並將其從DOCollection項目集對象中移除。

若要從DOCollection的DOItem對象,檢查DOCollection.h文件,你應該沿着如果沒有,他們仍可以通過動態核心數據爲您生成的

-(void)removeDOItemObjects:(NSSet *)value 

線的方法。在你的頭文件,你應該有沿着線的東西:

@property(nonatomic,retain) DOItem *items 

然後在實現文件,你應該沿着線的東西:那應該生成

@synthesize items 

適當的方法這些自動:

-(void)addItemsObject:(DOItem*)value 
-(void)addItems:(NSSet *)values 
-(void)removeItemsObject:(DOItem *)value 
-(void)removeItems:(DOItem *)values 
-(NSSet *)items 

請參閱「自定義一對多關係訪問器方法」here for more info

該方法在您創建數據模型和關聯的實現文件時爲您提供,並應由Core Data進行高度優化。然後,所有你需要做的刪除對象是沿着線的東西:

- (void) deleteList:(DOCollection *) collection { 

    // Remove all of them from the collection 
    [managedObjectContext performBlockAndWait:^{ 
     // Updated 01/10/2012 
     [collection removeItems:collection.items]; 
     NSError *error = nil; 
     if (![managedObjectContext save:&error]) { 
      NSLog(@"Core Data: Error saving context."); } 
     }; 
    }]; 

}

你可能要檢查的性能刪除使用此方法,並繼續爲用戶提供反饋用戶。如果性能是一個問題,考慮跨步,將設置分成塊,並在前進每個步驟之前執行上述方法,更新用戶界面等。

再次,我不確定您的應用程序體系結構,但乍一看,這看起來像這個問題。

祝你好運!

+0

謝謝!性能似乎不成問題。最後一個問題。 Xcode有沒有辦法在之後生成這些方法?我似乎無法找到一個功能,除了從頭開始創建它們並覆蓋我當前的自定義實現 – 2012-01-09 19:27:52

+0

對於延遲響應感到抱歉。請參閱最新的答案。 – timthetoolman 2012-01-11 03:44:45