2015-01-07 3 views
3

Итак, у меня есть куча объектов в Core Data и вы хотите, чтобы они автоматически удалялись через X дней (это было бы основано на NSDate). Я сделал несколько поисков, и кажется, что вы можете удалять только один основной объект данных за раз, а не группу из них, не говоря уже о тех, которые основаны на определенной дате. Я думаю, возможно, чтобы цикл проходил через каждый объект, но похоже, что это будет очень тяжелый процессор. Любые идеи о том, где я должен искать это? Благодарю.Удаление данных ядра после X количество дней

+0

возможно дубликат [CoreData удаление нескольких объектов] (http://stackoverflow.com/questions/14560900/coredata-delete-multiple-objects) – tkanzakic

+0

@tkanzakic это не дубликат, он знает, как удалить несколько объектов в цикле. Он специально спрашивает, что делать, делая это, было бы неприемлемо медленным и оставило бы приложение полностью невосприимчивым. –

+0

Вы рассмотрели новую функцию пакетного обновления Core Data в iOS 8? Он позволяет выполнять такие высокопроизводительные операции намного быстрее. – Abizern

ответ

2

Образец, удаляющий объекты один за другим, является правильным подходом.

Удаление объектов в Core Data чрезвычайно тяжело для процессора. Если это проблема, то Core Data не подходит для вашего проекта, и вы должны использовать что-то еще. Я рекомендую FCModel, в качестве легкой альтернативы, которая очень эффективна.

Если вы собираетесь использовать основные данные, рекомендуется выполнять большие операции на фоне NSOperationQueue, поэтому основное приложение не блокируется при удалении объектов. Вы должны быть очень осторожны с основными данными в нескольких потоках, подход состоит в том, чтобы иметь отдельный контекст управляемых объектов для каждого потока, как с использованием одного и того же постоянного координатора хранилища. Никогда не обменивайтесь управляемым объектом по потокам, но вы можете совместно использовать идентификатор объекта, чтобы получить вторую копию той же записи базы данных в другом контексте управляемых объектов.

В основном ваш фоновый поток создает новый контекст, удаляет все объекты в цикле, затем (в основном потоке желательно видеть документацию), сохраняя контекст фонового потока. Это объединит ваши изменения, если не возникнет конфликт (оба контекста изменяют один и тот же объект) - в этом сценарии у вас есть несколько вариантов, я бы просто прекратил всю операцию удаления и начал заново.

Apple, имеет хорошую документацию, доступную для всех вопросов и пример кода доступен здесь: https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdConcurrency.html

Это немного пугает, что вам нужно сделать некоторые серьезные домашние задания, но фактический код очень прост, как только вы получили ваш голова вокруг, как все работает. Или просто используйте FCModel, который предназначен для быстрых пакетных операций.

+2

FCModel - альтернатива в том смысле, что она является базой данных SQL. Основные данные не являются базой данных; это график отношений объектов, который имеет возможность сохранять данные в базе данных SQLite. – Abizern

+0

@ База данных Abizern представляет собой «Сбор данных, предназначенный для удобства и скорости поиска и поиска». Таким образом, базовые данные являются базой данных. Также в iOS SQLite - единственная опция сохранения данных, остальные два варианта, доступные в OS X, не разрешены в iOS. Двоичный хранилище данных и XML используют слишком много ОЗУ, что потенциально приводит к повреждению диска, что приводит к преждевременному сбою флэш-памяти. –

+0

Я бы пошел с FCModel, но у меня уже есть базовая база данных и пользовательская база людей, использующих приложение, насколько я знаю, вы не можете перенести данные из Core Data в FCModel. Кто-то упомянул обновления баз данных в iOS 8, это было бы хорошо? (Я немного новичок во всем этом) – mlevi

0

Это не так процессор тяжелых, как вы можете думать :) (конечно, это зависит от объема данных)

Вы можете использовать петлю

- (void)deleteAllObjects 
{ 
NSArray *allEntities = self.managedObjectModel.entities; 
for (NSEntityDescription *entityDescription in allEntities) 
{ 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    [fetchRequest setEntity:entityDescription]; 

    fetchRequest.includesPropertyValues = NO; 
    fetchRequest.includesSubentities = NO; 

    NSError *error; 
    NSArray *items = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; 

    for (NSManagedObject *managedObject in items) { 
     [self.managedObjectContext deleteObject:managedObject]; 
    } 

    if (![self.managedObjectContext save:&error]) { 
     NSLog(@"Error occurred"); 
    } 
} 
} 
+0

Это процессор тяжелый. Приложение, которое я написал, может занимать до 5 минут для цикла 'for {delete}. Эта же операция в FCModel занимает ~ 0,5 секунды. –

+0

Да, FCModel, конечно, лучше apporach, но некоторые просто хотят использовать Core Data. – sztembi

+0

Знаете ли вы, как я проверил бы дату - чтобы узнать, не старше ли она определенной даты? – mlevi

0

Как уже отмечалось, итерация объектов является единственный способ фактически удалить объекты в Core Data. Это один из тех случаев, когда подход Core Data приближается, потому что он просто не оптимизирован для такого использования.

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

Если у вас есть много объектов, которые необходимо удалить, и вы не хотите ждать завершения процесса, вы можете сначала подделать первоначальное удаление, а затем выполнить фактическое удаление, когда это удобно , Что-то вроде:

  1. Добавить пользовательский логический атрибут к типу объекта называется что-то вроде toBeDeleted со значением по умолчанию NO.
  2. Когда у вас есть куча объектов для удаления, установите toBeDeleted на YES на всех из них за один шаг, используя NSBatchUpdateRequest (новый в iOS 8).Этот класс в основном недокументирован, поэтому посмотрите на файл заголовка или на BNR blog post about it. Вы укажете имя свойства и новое значение атрибута, а Core Data будет массовым и быстрым обновлением.
  3. Убедитесь, что ваши запросы на выборку проверяют, что toBeDeleted - NO. Теперь объекты, помеченные для удаления, будут исключены при извлечении, даже если они все еще существуют.
  4. В какой-то момент - позже, но вскоре - запустите некоторый код в фоновом режиме, который извлекает и удаляет объекты с toBeDeleted, установленными на YES.
Смежные вопросы