2012-01-07 92 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