Mac OSX — основные данные не сохраняются

В моем приложении я использую два табличных представления, каждое из которых привязано к своему NSArrayController, а контроллеры массива настроены на использование объектов Core Data. Когда данные генерируются, создается NSObject, и значения сохраняются в нем с помощью obj.setValue(_:forKey:). После этого объект просто добавляется в контроллер массива с помощью ac.addObject().

Разве этого не должно быть достаточно, чтобы Core Data позаботился о постоянном хранении данных?

В любом случае, если я попытаюсь сохранить данные, вызвав saveAction(), он скажет мне, что MOC не имеет изменений (moc.hasChanges = false), поэтому он даже не начинает сохранять данные с помощью этого метода.

О чем еще мне нужно позаботиться, чтобы Core Data правильно хранил данные и подтверждал изменения?

Контроллеры массива устанавливаются в Interface Builder следующим образом:

  • Режим: Имя объекта
  • Имя объекта: «имя объекта в модели данных»
  • Подготавливает Содержимое проверено

Они также правильно привязаны к контексту управляемого объекта.

Упрощенный соответствующий код из моего приложения:

    /* Clear existing data. */
    let range:NSRange = NSMakeRange(0, arrayController.arrangedObjects.count);
    let indexSet:NSIndexSet = NSIndexSet(indexesInRange: range);
    arrayController.removeObjectsAtArrangedObjectIndexes(indexSet);

    let array = generateData();

    /* Generate data. */
    for i in 0 ..< array.count
    {
        let data = array[i];

        /* Create new data object. */
        var obj:NSObject = arrayController.newObject() as! NSObject;
        obj.setValue(data.name, forKey: "name");
        obj.setValue(data.type, forKey: "type");
        obj.setValue(data.category, forKey: "category");

        /* Add it to the array controller's contentArray. */
        arrayController.addObject(obj);
    }

ОБНОВИТЬ:

Похоже, что мое приложение создает четыре MOC при запуске. Я подозреваю, что способ добавления их в раскадровку для двух контроллеров массива неверен. Я добавил NSObject к двум контроллерам табличного представления (которые также содержат свои контроллеры массива) и установил их базовые классы как мой CoreDataDelegate (это мой класс для основного кода данных, который обычно находится в AppDelegate). Я подозреваю, что именно здесь создаются несколько экземпляров CoreDataDelegate. Вопрос в следующем: как мне правильно это сделать, чтобы контроллеры массива могли получить доступ к моему классу CoreDataDelegate?


person BadmintonCat    schedule 04.05.2015    source источник
comment
Вы создаете NSObject? Показать код   -  person Wain    schedule 04.05.2015
comment
Мой код немного сложнее и разделен на несколько классов и т. д., но я попытаюсь сделать комбинированный пример...   -  person BadmintonCat    schedule 04.05.2015
comment
Я добавил пример кода.   -  person BadmintonCat    schedule 04.05.2015
comment
И вы проверили, что код работает, и контроллер массива существует в это время, и результаты отображаются на экране?   -  person Wain    schedule 04.05.2015
comment
Да иначе все работает. Данные отображаются в таблице и т. д. One Details. Мой основной код делегата данных находится в собственном классе, а не в AppDelegate, и этот класс также расширяет NSObject. Я думаю, это должно быть хорошо.   -  person BadmintonCat    schedule 04.05.2015
comment
Все должно быть в порядке. Когда и как вы сохраняете (можете ли вы иметь несколько контекстов или нет контекста)?   -  person Wain    schedule 04.05.2015
comment
чтобы следовать за @wain вниз по кроличьей норе ... вы вызываете save в контексте, который затем вызывает его в координаторе постоянства ... который затем сохраняет его там, где это когда-либо уместно (что в зависимости от вашей конфигурации может быть ОЗУ (что было бы volatile, или диск, или облако/диск и т.д.))   -  person Grady Player    schedule 04.05.2015
comment
Вы можете быть правы с несколькими контекстами. Когда я выхожу из них, я получаю несколько с разными идентификаторами. Что-то там выглядит не так, хотя я использую стандартный код основных данных, который поставляется с новым проектом Xcode.   -  person BadmintonCat    schedule 04.05.2015
comment
Я думаю, что нашел проблему. Пожалуйста, смотрите мой обновленный текст выше.   -  person BadmintonCat    schedule 04.05.2015


Ответы (1)


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

class CoreDataDelegate : NSObject
{
    static let instance = CoreDataDelegate();
    ...
}

Затем у меня есть ссылка на него в моем AppDelegate (который также является синглтоном)...

@NSApplicationMain
class AppDelegate : NSObject, NSApplicationDelegate
{
    static let instance = AppDelegate();
    let coreData:CoreDataDelegate;

    override init()
    {
        coreData = CoreDataDelegate.instance;
        super.init();
    }

    ...
}

Затем в раскадровке я добавил NSObject к двум моим контроллерам табличного представления и установил базовый класс в AppDelegate. А затем привязал ArrayControllers к moc через AppDelegate/coreData.moc.

Теперь создан только один экземпляр CoreDataDelegate (и, следовательно, только один moc), и я могу с радостью сообщить, что теперь сохранение работает!

person BadmintonCat    schedule 04.05.2015