2013-07-04 108 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