Сбросьте CoreData персистентное хранилище

В основном то, что я пытаюсь сделать, должно вытереть все данные в моем CoreData персистентное хранилище, затем импортировать новые данные. Как Вы сделали бы это? Кажется, что простое решение является вызовом [NSPersistentStoreCoordinator removePersistentStore:error:] и затем удалите файл. Это - доступная лучшая практика? Действительно ли это ориентировано на многопотоковое исполнение?

Большое спасибо,

#

Вопрос 0.1: был

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

Я добавил следующее resetPersistentStore метод в моем AppDelegate (persistentStoreCoordinatorдан для ссылки):

// ...
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
// ...

/**
 Returns the persistent store coordinator for the application.
 If the coordinator doesn't already exist, it is created and the application's store added to it.
 */
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }

    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: kPersistentStoreFilename]];

    NSError *error = nil;
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }    

    return persistentStoreCoordinator;
}

/**
 * Will remove the persistent store
 */
- (NSPersistentStoreCoordinator *)resetPersistentStore {
    NSError *error;

    [managedObjectContext lock];

    // FIXME: dirty. If there are many stores...
    NSPersistentStore *store = [[persistentStoreCoordinator persistentStores] objectAtIndex:0];

    if (![persistentStoreCoordinator removePersistentStore:store error:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }  

    // Delete file
    if (![[NSFileManager defaultManager] removeItemAtPath:store.URL.path error:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    } 

    // Delete the reference to non-existing store
    [persistentStoreCoordinator release];
    persistentStoreCoordinator = nil;

    NSPersistentStoreCoordinator *r = [self persistentStoreCoordinator];
    [managedObjectContext unlock];

    return r;
}

Затем, по моему мнению, я делаю (в другом потоке, так как я использую MBProgressHUD:

PatrimoineAppDelegate *appDelegate = (PatrimoineAppDelegate *)[[UIApplication sharedApplication] delegate]; 
// Delete everything
[appDelegate resetPersistentStore];

И я добираюсь EXC_BAD_ACESS...

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

16
задан 4 revs, 2 users 65% 11 December 2014 в 03:15
поделиться

2 ответа

Если ваша цель - очистить хранилище данных и перезагрузить его новой информацией, вам может быть лучше использовать NSManagedObjectContext reset , а затем загрузить новые данные.

Из документации NSManagedObjectContext

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

Удаление постоянного хранилища и использование контекста управляемого объекта, связанного с хранилищем, вероятно, является причиной ошибки.

8
ответ дан 30 November 2019 в 21:53
поделиться

Меню «сухари» является повторяющимся образцом в большинстве приложений Rails. Для решения этой проблемы я создал и выпустил плагин под названием breadcrumbs _ on _ rails .

Вы определяете сухари в контроллере

class MyController

  add_breadcrumb "home", root_path
  add_breadcrumb "my", my_path

  def index
    # ...

    add_breadcrumb "index", index_path
  end

end

и визуализируете их в своем представлении.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title>untitled</title>
</head>

<body>
  <%= render_breadcrumbs %>
</body>
</html>

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

-121--2293356-

Существуют ситуации, когда требуется выполнить/запустить некоторые сценарии на удаленном компьютере/сервере (которые завершатся автоматически) и отсоединиться от сервера.

Например: Сценарий, запущенный на рамке, которая при выполнении

  1. берет модель и копирует ее на удаленный сервер
  2. , создает сценарий для запуска моделирования с моделью и передает его на сервер
  3. запускает сценарий на сервере и отключает
  4. . Задача запущенного сценария состоит в том, чтобы запустить моделирование на сервере и после завершения (для завершения потребуется несколько дней) скопируйте результаты обратно в клиент.

Я бы использовал следующую команду:

ssh remoteserver 'nohup /path/to/script `</dev/null` >nohup.out 2>&1 &'

@ CKeven, вы можете поместить все эти команды в один сценарий, протолкнуть его на удаленный сервер и инициировать его следующим образом:

echo '#!/bin/bash  
rm -rf statuslist  
mkdir statuslist  
chmod u+x ~/monitor/concat.sh  
chmod u+x ~/monitor/script.sh  
nohup ./monitor/concat.sh &  
' > script.sh

chmod u+x script.sh

rsync -azvp script.sh remotehost:/tmp

ssh remotehost '/tmp/script.sh `</dev/null` >nohup.out 2>&1 &'

Надеюсь, это работает; -)

Правка: Также можно использовать ssh user @ host 'screen -S SessionName -d -m «/path/to/executable »'

Создание сеанса отсоединенного экрана и выполнение в нем целевой команды

-121--2130573-

Вот решение. Может быть несколько более элегантных вариантов (lock...), но этот работает.

/**
 * Will remove the persistent store
 */
- (NSPersistentStoreCoordinator *)resetPersistentStore {
    NSError *error = nil;

    if ([persistentStoreCoordinator persistentStores] == nil)
        return [self persistentStoreCoordinator];

    [managedObjectContext reset];
    [managedObjectContext lock];

    // FIXME: dirty. If there are many stores...
    NSPersistentStore *store = [[persistentStoreCoordinator persistentStores] lastObject];

    if (![persistentStoreCoordinator removePersistentStore:store error:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }  

    // Delete file
    if ([[NSFileManager defaultManager] fileExistsAtPath:store.URL.path]) {
        if (![[NSFileManager defaultManager] removeItemAtPath:store.URL.path error:&error]) {
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        } 
    }

    // Delete the reference to non-existing store
    [persistentStoreCoordinator release];
    persistentStoreCoordinator = nil;

    NSPersistentStoreCoordinator *r = [self persistentStoreCoordinator];
    [managedObjectContext unlock];

    return r;
}
4
ответ дан 30 November 2019 в 21:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: