2013-07-04 5 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? И, возможно, даже объекты с другой стороны этих отношений имеют одинаковые правила удаления? Основные данные будут уничтожать все эти ошибки отдельно.

В этом случае вы должны PreFetch этих отношений при выборке для объектов для удаления:

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

это увеличит использование дискового ввода-вывода, использование батареи. Не определенно. Нужно запустить метод сохранения в фоновом потоке, если в работе слишком много строк/изменений. –

+0

Если я использую ваш код, это требует удвоенного времени. [managedObjectContext save: & saveError]; не должен находиться в цикле for. – vin

Смежные вопросы