优化联系人删除

Posted

技术标签:

【中文标题】优化联系人删除【英文标题】:Optimizing contacts deletion 【发布时间】:2013-07-04 13:01:17 【问题描述】:

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

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

+(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];

任何帮助将不胜感激

谢谢

【问题讨论】:

+1 因为问题涉及应用程序的性能。 NSInteger *contactsIdentifier=1; 看起来很可疑。它是一个指向 NSInteger 的指针,但您可能想使用 NSInteger 本身。 【参考方案1】:

也许PersonEvent 实体具有使用Cascade 删除规则配置的关系?甚至这些关系另一端的对象也可能有类似的删除规则? Core Data 将单独触发所有这些故障。

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

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];

【讨论】:

【参考方案2】:

首先我想说“好问题”。并欣赏您担心的事情。

答案:-

在核心数据 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..");

希望对您有所帮助...!

【讨论】:

这会增加磁盘 IO 使用率,电池使用率。绝对不是解决方案。如果操作的行/更改太多,应该在后台线程上运行保存方法 如果我使用你的代码,它需要双倍的时间。 [managedObjectContext 保存:&saveError];不应该在 for 循环中。

以上是关于优化联系人删除的主要内容,如果未能解决你的问题,请参考以下文章

优化数以千计的 SQLite 查询 android

从 android 联系人中删除单个联系人

如何删除一个联系人中有多个号码的iphone联系人?

无法删除共享联系人

这是从iPhone删除联系人的正确方法吗?

如何以编程方式在android 10中恢复已删除的联系人