2013-07-04 107 views
1

我已经复制了所有本地联系人并将它们存储在核心数据中,现在,当我使用时间分析器工具时,它显示我正在花费大量时间从我的应用中删除本地联系人。可以提供任何人我使用任何优化技术来改善我的代码和应用程​​序性能。优化联系人删除

这是我从核心数据的联系人删除代码:

+(void)deleteContacts 
{ 
    [[LoadingIndicator currentIndicator]displayActivity:@"Deleting Old contacts"]; 

    //fetch the data from core data and delete them because you are going to sync again 
    AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate]; 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    // Edit the entity name as appropriate. 
    NSManagedObjectContext *managedObjectContext=[appDelegate managedObjectContext]; 

    fetchRequest.entity = [NSEntityDescription entityForName:@"PersonEvent" inManagedObjectContext:managedObjectContext]; 

    NSInteger *contactsIdentifier=1; 
    fetchRequest.predicate = [NSPredicate predicateWithFormat:@"sourceflag == %d", contactsIdentifier]; 


    NSArray * persons = [managedObjectContext executeFetchRequest:fetchRequest error:nil]; 



    //error handling goes here 
    if (persons.count>0) { 


     for (NSManagedObject * person in persons) { 
      [managedObjectContext deleteObject:person]; 

     } 
    } 
    NSError *saveError = nil; 
    [managedObjectContext save:&saveError]; 
    [[LoadingIndicator currentIndicator]displayCompleted:@"Done"]; 
    [[LoadingIndicator currentIndicator]hide]; 
    NSLog(@"Finished deleting local contacts.."); 
} 

的时间探查表明了我94.3%的时间都花在 [managedObjectContext节省:& saveError]。

任何帮助,将不胜感激

感谢

+0

+1因为问题有关于应用性能的问题。 –

+0

'NSInteger * contactsIdentifier = 1;'看起来很可疑。它是一个指向NSInteger的指针,但你可能想要使用NSInteger本身。 – eofster

回答

0

也许PersonEvent实体具有配置了Cascade删除规则的关系?甚至可能是这些关系的另一方的对象具有相似的删除规则?核心数据将单独触发所有这些故障。

在这种情况下获取的要删除的对象时,你应该预取这些关系:

fetchRequest.relationshipKeyPathsForPrefetching 
    = @[@"relationshipName", 
     @"anotherRelationship", 
     @"anotherRelationship.subrelationship"]; 

如果没有对象级联连同PersonEvent删除,而你只是删除了很多PersonEvent,你可能尝试批量保存。这可能不会减少保存所有删除所需的总时间,但它不会锁定上下文,持久存储协调器和存储文件本身,以实现一次巨大的保存。

const NSUInteger kBatchSize = 200; 
NSUInteger currentCount = 0; 
for (NSManagedObject *person in persons) { 
    currentCount++; 
    [context deleteObject:person]; 
    if (currentCount == kBatchSize) { 
     currentCount = 0; 
     NSError *error; 
     BOOL saved = [context save:&error]; 
    } 
} 

if (currentCount != 0) { 
    NSError *error; 
    BOOL saved = [context save:&error]; 
} 
0

首先,我会说:“好问题”。欣赏你所关心的事情。

答: -

在核心数据managedObjectContext仍然有在同一个对象的所有更改它不是更新到实际的数据库。

所以当[managedObjectContext save:&saveError]叫它开始更新它到核心数据库。所以你可以通过下面的方式进行优化&检查时间配置文件的性能。

NSError *saveError = nil; 
if (persons.count>0) { 


    for (NSManagedObject * person in persons) { 
     [managedObjectContext deleteObject:person]; 
     [managedObjectContext save:&saveError]; 
    } 
} 
[[LoadingIndicator currentIndicator]displayCompleted:@"Done"]; 
[[LoadingIndicator currentIndicator]hide]; 
NSLog(@"Finished deleting local contacts.."); 

希望它可以帮助你......!

+0

这会增加磁盘IO使用率,电池使用量。绝对不是解决方案。如果操作有太多的行/更改,应该在后台线程上运行save方法 –

+0

如果我使用您的代码,则需要两倍的时间。 [managedObjectContext save:&saveError];不应该在for循环中。 – vin