Управляемый объект Core Data не видит связанные объекты до перезапуска Simulator

Получил Stumper (по крайней мере для меня).

Я использую iOS 5.0 с ARC и Core Data внутри UIManagedDocument.

У меня есть сущность (группа), имеющая отношение ко многим (называемые людьми) к сущности (личности). Когда я добавляю новую группу и затем добавляю нового человека (устанавливая отношение человека.group к новой группе), я не могу получить связанных людей, используя предикат для объекта Person, где ("group == %@", myGroup). Я также попытался использовать сеттер addPerson для группы.

Если я выключу симулятор XCode и перезапущу его, он распознает отношения, созданные в предыдущем запуске, я даже могу добавить новых людей в существующий объект группы. Я просто не могу добавить новую группу, а затем добавить людей, не выключая симулятор (или устройство, если я работаю на устройстве), чтобы увидеть взаимосвязь.

Если я посчитаю [group.people count], сразу после добавления новой группы и связанного с ней лица, я получу правильный номер. Но выборка с предикатом не работает, пока я не перезапущу приложение.

Похоже, что managedObjectContext UIManagedDocument не видит отношения. Я попытался сохранить контекст, сохранить context.parentContext и сохранить документ. Ничего из этого не помогло.

Любые идеи были бы хорошы!

2 ответа

Решение

UIManagedDocument сохранит, ну, в основном, когда это будет похоже; Вы не можете контролировать, когда это произойдет. Это, однако, безусловно, сэкономит на завершении работы приложения, поэтому вы видите вставки при перезапуске.

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

Чтобы сделать их постоянными и пригодными для использования, попробуйте следующее после выполнения ваших дополнений. Предполагая, что у вас есть UIManagedDocument в качестве ивара:

- (void)performUpdate
{
    NSManagedObjectContext * context = self.managedDocument.managedObjectContext;
    NSSet                  * inserts = [context insertedObjects];

    if ([inserts count])
    {
        NSError * error = nil;

        if ([context obtainPermanentIDsForObjects:[inserts allObjects]
                                            error:&error] == NO)
        {
            NSLog(@"BAM! %@", error);
        }
    }

    [self.managedDocument updateChangeCount:UIDocumentChangeDone];
}

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

И да, мне это тоже кажется немного странным, но, похоже, это правильный способ сделать что-то с UIManagedDocument в игре.

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

У меня была похожая проблема, обновление не помогло мне. Это сделал:

NSArray *insertedObjs = [[self.managedObjectContext insertedObjects] allObjects];
if ([insertedObjs count] > 0) {
    NSError * error;
    [self.managedObjectContext obtainPermanentIDsForObjects:insertedObjs error:&error];
}

Я запускаю это после того, как вставил объекты и перед сохранением.

Другие вопросы по тегам