Очистка CoreData и все, что внутри
Я новичок в CoreData и этом приложении, которое его использует.
И теперь я работаю над функцией, которая очищает все основные данные при выходе из приложения.
У меня есть 2 файла sqllite (по какой-то причине они считали, что это удобно)
Как я могу удалить оба файла всех данных и reset их в состояние dataless?
Я пробовал много способов, следуя инструкциям, на SO.
Как очистить / reset все отношения CoreData в отношениях один-ко-многим
как удалить все объекты из основных данных
Все они кажутся мне неудачными.
Теперь мне интересно, что я делаю неправильно? И, возможно, кто-то может объяснить мне, как reset мои 2 файла CoreData надлежащим образом.
EDIT:
//should clear the whole coredata database. mainly used for logout mechanism
-(void)resetCoreData
{
for (NSPersistentStore *store in self.persistentStoreCoordinator.persistentStores)
{
// NSPersistentStore *store = self.persistentStoreCoordinator.persistentStores[0];
NSError *error;
NSURL *storeURL = store.URL;
DLog(@"storeURL: %@", storeURL);
NSPersistentStoreCoordinator *storeCoordinator = self.persistentStoreCoordinator;
[storeCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtPath:storeURL.path error:&error];
DLog(@"There are erreurs: %@", error);
// [self addDefaultData];
}
_persistentStoreCoordinator = nil;
_managedObjectContext = nil;
_managedObjectModel = nil;
}
Это, похоже, не очищает CoreData для меня.
EDIT2:
- (NSManagedObjectContext *)managedObjectContext
{
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return _managedObjectContext;
}
- (NSManagedObjectModel *)managedObjectModel
{
if (__managedObjectModel != nil) {
return __managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyName" withExtension:@"momd"];
__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return __managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (__persistentStoreCoordinator != nil) {
return __persistentStoreCoordinator;
}
NSString *storePath = [[self applicationDocumentsDirectory]
stringByAppendingPathComponent:@"MyName.sqlite"];
NSFileManager *fileManager = [NSFileManager defaultManager];
// If the expected store doesn't exist, copy the default store.
if (![fileManager fileExistsAtPath:storePath]) {
NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"MyName" ofType:@"momd"];
if (defaultStorePath) {
[fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
}
}
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
//Check to see what version of the current model we're in. If it >= 2.0,
//then and ONLY then check if migration has been performed...
NSSet *versionIdentifiers = [[self managedObjectModel] versionIdentifiers];
DLog(@"Which Current Version is our .xcdatamodeld file set to? %@", versionIdentifiers);
if ([versionIdentifiers containsObject:@"2.0"])
{
BOOL hasMigrated = YES;
if (hasMigrated==YES) {
storePath = nil;
storePath = [[self applicationDocumentsDirectory]
stringByAppendingPathComponent:@"MyName2.sqlite"];
}
}
NSURL *storeUrl = [NSURL fileURLWithPath:storePath];
NSError *error;
NSDictionary *pscOptions = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:NO], NSInferMappingModelAutomaticallyOption,
nil];
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeUrl
options:pscOptions
error:&error]) {
DLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return __persistentStoreCoordinator;
}
Изменить 3:
Я все еще ищу способ reset my CoreData, как если бы я удалил все приложение и снова запустил его. Обычные способы сделать это не работают для моего дела. И есть 2 файла sqllite. Есть подсказки о миграции, которые произошли в какой-то момент приложения, но я не слишком уверен, когда и как. Журналы ошибок не показывают ничего полезного.
Я не ищу самый эффективный способ. Именно так.
Помогите мне, и щедрость ваша.
Изменить 4:
КОНЕЧНЫЙ РЕЗУЛЬТАТ:
Казалось, у моего устаревшего кода появился второй экземпляр ManagedObjectContext. В тот момент, когда я получил его и сделал с ним флеш-функцию. Оба файла sqlite исчезли, как было необходимо.
Спасибо всем, кто приложил усилия к моей проблеме.
Ответы
Ответ 1
попробуйте следующий метод очистки базы данных, он отлично подходит для меня.
-(void) flushDatabase{
[__managedObjectContext lock];
NSArray *stores = [__persistentStoreCoordinator persistentStores];
for(NSPersistentStore *store in stores) {
[__persistentStoreCoordinator removePersistentStore:store error:nil];
[[NSFileManager defaultManager] removeItemAtPath:store.URL.path error:nil];
}
[__managedObjectContext unlock];
__managedObjectModel = nil;
__managedObjectContext = nil;
__persistentStoreCoordinator = nil;
}
Ответ 2
NSPersistentStoreCoordinator *storeCoordinator = self.persistentStoreCoordinator;
[storeCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtPath:storeURL.path error:&error];
Итак, вы удаляете постоянное хранилище из координатора постоянного хранилища, а затем пытаетесь удалить файл. Но просто удалить хранилище у координатора недостаточно, чтобы гарантировать, что файл, связанный с хранилищем, был закрыт, а если он не будет, файловая система, вероятно, не позволит вам удалить файл. Я не могу сказать из вашего вопроса, используете ли вы здесь ARC, но так как вы говорите, что у старого кода есть хороший шанс, что вы этого не делаете. В любом случае, если удаление хранилища заставляет его автоматически освобождаться, а не выпускать, или если вы храните любые другие ссылки на хранилище в любом месте, то магазин не будет освобожден только потому, что вы удалили его из координатора, файл может оставаться открытым, и удаление файла не удастся.
Хороший способ увидеть, что действительно происходит, помимо поиска объекта ошибки, предоставляемого -removeItemAtPath:error:
, - это посмотреть в файловой системе и посмотреть, остается ли файл после попытки удалить его, Перейдите в окно "Организатор", выберите свое устройство и приложение и загрузите копию песочницы приложений. Затем вы сможете увидеть, действительно ли файл удаляется.
Если вы видите, что файлы удаляются, как вы думаете, они должны быть, а затем искать другие способы восстановления данных. Если UserA выходит из системы, а затем UserB регистрируется в приложении во время его работы, вы уверены, что начали с нового контекста управляемых объектов? Возможно ли, что данные UserA остаются в MOC? Затем он может быть выписан при создании и добавлении нового магазина. Другая возможность, которая возникает у меня, это то, что iCloud "помогает" здесь. Я вижу, что ваши файлы данных хранятся в папке "Документы", и iOS обычно пытается сохранить файлы в этом каталоге, поддерживаемые iCloud. Возможно, когда вы создадите новый магазин для данных UserB, iCloud добавляет записи UserA обратно в этот магазин. (Кажется маловероятным - я уверен, что iCloud более изощрен, чем это, но что-то проверить.)
Ответ 3
Я использую эту функцию в AppDelegate одного из моих приложений...
- (void)deleteAllCoreData
{
NSPersistentStore *store = self.persistentStoreCoordinator.persistentStores[0];
NSError *error;
NSURL *storeURL = store.URL;
NSPersistentStoreCoordinator *storeCoordinator = self.persistentStoreCoordinator;
[storeCoordinator removePersistentStore:store error:&error];
[[NSFileManager defaultManager] removeItemAtPath:storeURL.path error:&error];
__persistentStoreCoordinator = nil;
__managedObjectContext = nil;
__managedObjectModel = nil;
[self addDefaultData];
}
Он удаляет постоянное хранилище, которое использует CoreData, и оставляет его таким образом, чтобы новый был настроен при повторном доступе к основным данным.
Это метод, описанный во второй ссылке, которую вы предоставили.
Ответ 4
Если ваше приложение может создавать файлы, просто удалите их, когда приложение завершает работу.
Если у вас есть представление о базе данных с ценной информацией о схеме, и вам просто нужно обрезать файл, это не так в случае с основными данными... Схема находится в скомпилированных моделях сущностей и xcwhatever файлах.
Также я должен был просто прочитать это неправильно, потому что если вы хотите, чтобы данные ядра не были постоянными, вы используете неправильный инструмент.