优化联系人删除
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 循环中。以上是关于优化联系人删除的主要内容,如果未能解决你的问题,请参考以下文章