Очистка CoreData и все, что внутри

Я довольно новичок в CoreData и это приложение, которое использует его. И в настоящее время я работаю над функцией, которая очищает все основные данные, когда я выхожу из приложения.

у меня есть 2 файла sqllite (по какой-то причине они думали, что это удобно)

Как очистить оба файла от всех данных и сбросить их в состояние без данных?

Я пробовал много способов, следуя руководствам, на SO.

Как очистить/сбросить все CoreData в один-ко-многим отношения

как удалить все объекты из основных данных

Они все, кажется, терпят неудачу для меня. Теперь мне интересно, что я делаю не так? И, возможно, кто-то может объяснить мне, как правильно сбросить мои файлы 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's >= 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: Я все еще ищу способ сбросить CoreData, как будто я удалил все приложение и запустил его снова. Обычные способы этого не работают в моем случае. И есть 2 файла sqllite. Есть намеки на миграцию, которая имела место в какой-то момент в приложении, но я не слишком уверен, когда и как. Журналы ошибок не показывают ничего полезного.

Я не ищу самый эффективный способ. Просто так.

помоги мне и награда твоя.

изменить 4: ОКОНЧАТЕЛЬНЫЙ РЕЗУЛЬТАТ: Казалось, у моего устаревшего кода была секунда. Экземпляр ManagedObjectContext. В тот момент, когда я поднял его и сделал с ним флеш-функцию. Оба sqlite-файла исчезли по мере необходимости.

спасибо всем, что приложили усилия в моей проблеме.

4 ответов


попробуйте следующий метод, чтобы очистить базу данных, он идеально подходит для меня.

-(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;
}

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 более сложный, чем - но что-то проверять.)


Я использую эту функцию в 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, и оставляет его, чтобы создать новое при повторном доступе к основным данным.

Это способ описано во второй ссылке, которую вы предоставили.


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

также Я, должно быть, просто прочитал его неправильно, потому что если вы хотите, чтобы основные данные не были постоянными, то вы используете неправильный инструмент.