Подтвердить что ты не робот

Есть ли способ создать экземпляр объекта NSManagedObject без его вставки?

У меня есть пользовательский интерфейс для вставки транзакции. как только пользователь нажимает на плюс, он получает экран, и я хочу создать экземпляр объекта Core Data NSManagedObject, чтобы пользователь мог работать над ним. Затем, когда пользователь нажимает кнопку "Сохранить", я вызываю функцию сохранения.

поэтому до кода:

transaction = (Transaction *)[NSEntityDescription insertNewObjectForEntityForName:@"Transaction" inManagedObjectContext:self.managedObjectContext];
//even if i dont call save: its going to show up on my table
[self.managedObjectContext save:&error]

P.S Я использую NSFetchedResultsController в этой таблице, и я вижу, что NSFetchedResultsController вставляет раздел и объект в таблицу.

Моя мысль заключается в том, что есть способ создать экземпляр транзакции NSManagedObject, я мог бы обновить его с сохранением до тех пор, пока клиент не перейдет к.

4b9b3361

Ответ 1

Существует фундаментальная проблема с использованием nil MOC: объекты в разных MOC не должны ссылаться друг на друга — это, по-видимому, также применяется, когда одна сторона отношения имеет нулевой MOC. Что произойдет, если вы сохраните? (Что происходит, когда сохраняется другая часть вашего приложения?)

Если у вашего объекта нет отношений, то есть много вещей, которые вы можете сделать (например, NSCoding).

Возможно, вы сможете использовать -[NSManagedObject isInserted] в NSPredicate (предположительно это ДА между вставкой и успешной сохранностью). В качестве альтернативы вы можете использовать свойство переходного процесса с тем же поведением (установите его в YES в awakeFromInsert и NO в willSave). Обе эти проблемы могут быть проблематичными, если сохраняется другая часть вашего приложения.

Использование второго MOC - это то, что, как предполагается, используется CoreData; он автоматически обрабатывает обнаружение и разрешение конфликтов. Конечно, вы не хотите создавать новый MOC каждый раз, когда есть изменения; может быть смутно иметь один MOC для несохраненных изменений медленным "пользовательским потоком", если вы не возражаете, чтобы некоторые части пользовательского интерфейса видели несохраненные изменения в других частях (накладные расходы на связь между MOC незначительны).

Ответ 2

За что стоит, Маркус Зарра, похоже, продвигает контекстный подход nil, утверждая, что это дорого для создания нового контекста. Для получения дополнительной информации см. этот ответ к аналогичному вопросу.

Обновление

В настоящее время я использую подход с контекстом nil и столкнулся с чем-то, что может представлять интерес для других. Чтобы создать управляемый объект без контекста, вы используете метод initWithEntity:insertIntoManagedObjectContext: NSManagedObject. Согласно документации Apple для этого метода:

Если context не nil, этот метод вызывает [context insertObject:self](что приводит к тому, что awakeFromInsertвызывается).

Значение здесь важно. Использование контекста nil при создании управляемого объекта предотвратит вызов insertObject: и, следовательно, предотвратит вызов awakeFromInsert. Следовательно, любая инициализация объекта или установка значений свойств по умолчанию, выполненных в awakeFromInsert, не будут выполняться автоматически при использовании контекста nil.

Нижняя строка: при использовании управляемого объекта без контекста awakeFromInsert не будет вызываться автоматически, и вам может потребоваться дополнительный код для компенсации.

Ответ 3

вот как я это обработал:

При загрузке, где мы знаем, что имеем дело с новой транзакцией, я создал вне контекста один.

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Transaction" inManagedObjectContext:self.managedObjectContext];
        transaction = (Transaction *)[[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:nil];

тогда, когда дело дошло до установления отношения, я сделал это:

if( transaction.managedObjectContext == nil){
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Category" inManagedObjectContext:self.managedObjectContext];
        Category *category = (Category *)[[NSManagedObject alloc] initWithEntity:entity insertIntoManagedObjectContext:nil];
        category.title = ((Category *)obj).title;
        transaction.category = category;
        [category release];
    }
    else {
        transaction.category = (Category *)obj;
    }

и в конце для сохранения:

if (transaction.managedObjectContext == nil) {
        [self.managedObjectContext insertObject:transaction.category];
        [self.managedObjectContext insertObject:transaction];
    }
    //NSLog(@"\n saving transaction\n%@", self.transaction);

    NSError *error;
    if (![self.managedObjectContext save:&error]) {
        // Update to handle the error appropriately.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);  // Fail
    }

Ответ 4

Вы можете вставить NSManagedObjectContext с помощью -[NSManagedObject initWithEntity:insertIntoManagedObjectContext:], передав nil для контекста управляемого объекта. Разумеется, вы должны назначить его контексту (используя -[NSManageObjectContext insertObject:] перед сохранением. Это, насколько мне известно, не является действительно намеченным шаблоном в Core Data, однако (но см. @mzarra answer здесь). Существуют некоторые сложные проблемы с упорядочением (т.е. убедиться, что экземпляр присваивается контексту, прежде чем он ожидает его наличия и т.д.). Более стандартный шаблон - создать новый управляемый объект контекст и вставьте новый объект в этот контекст. Когда пользователь сохраняет, сохраняет контекст и обрабатывает NSManagedObjectDidSaveNotification, чтобы объединить изменения в ваш "основной" контекст. Если пользователь отменяет транзакцию, вы просто сбрасываете контекст и продолжайте свой бизнес.

Ответ 5

NSManagedObject может быть создан с использованием nil в качестве контекста, но если другие NSManagedObjects, с которыми он должен ссылаться, приведет к ошибке. Как я это делаю, я передаю контекст на экран назначения и создаю NSManagedObject на этом экране. Внесите все изменения в другие NSManagedObjects. Если пользователь удаляет кнопку отмены, я удаляю NSManagedObject и сохраняю контекст. Если пользователь удаляет кнопку сохранения, я обновляю данные в NSManagedObject, сохраняю его в контексте и отпускаю на экране. На исходном экране я обновляю таблицу с помощью перезагрузки.

Удаление NSManagedObject на целевом экране дает ключевое время для обновления файла. Обычно вам достаточно времени, чтобы вы не увидели изменения в таблице. В приложении iPhone Calendar у вас есть задержка с момента его сохранения до времени, отображаемого в виде таблицы. Это можно считать хорошей вещью с точки зрения пользовательского интерфейса, что ваш пользователь сосредоточится на только что добавленной строке. Надеюсь, это поможет.

Ответ 6

transaction = (Transaction *)[NSEntityDescription insertNewObjectForEntityForName:@"Transaction" inManagedObjectContext:nil];

если последний параметр равен nil, он вернет объект NSManagedObject без сохранения в db