Могу ли я создать новый экземпляр моего пользовательского класса управляемых объектов без прохождения NSEntityDescription? - PullRequest
7 голосов
/ 25 января 2010

Из примера Apple, у меня есть это:

Event *event = (Event*)[NSEntityDescription 
    insertNewObjectForEntityForName:@"Event" 
             inManagedObjectContext:self.managedObjectContext];

Event наследуется от NSManagedObject. Есть ли способ избежать этого странного вызова NSEntityDescription и вместо этого просто alloc+init каким-то образом напрямую Event класс? Должен ли я написать свой собственный инициализатор, который просто выполняет эти действия выше? Или NSManagedObject уже достаточно умен, чтобы сделать это?

Ответы [ 4 ]

5 голосов
/ 25 января 2010

NSManagedObject предоставляет метод с именем initWithEntity:insertIntoManagedObjectContext:. Вы можете использовать это для создания более традиционной пары alloc / init. Имейте в виду, что возвращаемый объект не автоматически выпущен.

3 голосов
/ 22 февраля 2011

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

Сначала вам нужно создать сущность:

// This line creates the proper description using the managed context and entity name. 
// Note that it uses the managed object context
NSEntityDescription *ent = [NSEntityDescription entityForName:@"Location" inManagedObjectContext:[self managedContext]];

// This line initialized the entity but does not insert it into the managed object context.    
currentEntity = [[Location alloc] initWithEntity:ent insertIntoManagedObjectContext:nil];

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

[self managedContext] insertObject:currentEntity

Обратите внимание, что в этих примерах объект currentEntity был определен в заголовочном файле следующим образом:

id currentEntity
1 голос
/ 03 июля 2010

Я нашел окончательный ответ от Подробнее о разработке iPhone 3 Дейва Марка и Джеффа ЛеМарша.

Если вас действительно беспокоит, что вы используете метод на NSEntityDescrpiton вместо NSManagedObjectContext для вставки нового объекта в NSManagedObjectContext, вы можете использовать категорию для добавления метода экземпляра до NSManagedObjectContext.

Создайте два новых текстовых файла с именами NSManagedObject-Insert.h и NSManagedObject-Insert.m .

В NSManagedObject-Insert.h введите следующий код:

import <Cocoa/Cocoa.h>
@interface NSManagedObjectContext (insert)
- (NSManagedObject *)insertNewEntityWithName:(NSString *)name;
@end

В NSManagedObject-Insert.m , поместите этот код:

#import "NSManagedObjectContext-insert.h"

@implementation NSManagedObjectContext (insert)
- (NSManagedObject *)insertNewEntityWithName:(NSString *)name
{
return [NSEntityDescription insertNewObjectForEntityForName:name inManagedObjectContext:self];
}
@end

Вы можете импортировать NSManagedObject-Insert.h куда угодно, чтобы использовать этот новый метод. Затем замените вызовы вставки на NSEntityDescription, как этот:

NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];

с более коротким и интуитивно понятным:

[context insertNewEntityWithName:[entity name]];

Разве категории не велики?

1 голос
/ 25 января 2010

Чтобы заставить его работать должным образом, есть много вещей, которые нужно сделать. -insertNewObject: ... безусловно, самый простой способ, странный или нет. В документации написано:

Управляемый объект отличается от других объекты в трех основных направлениях - управляемый объект ... существует в окружающей среде определяется его контекстом управляемого объекта ... поэтому много работы сделать, чтобы создать новый управляемый объект и правильно интегрировать его в Базовая инфраструктура данных ... вы не рекомендуется переопределять initWithEntity: insertIntoManagedObjectContext:

Тем не менее, вы все еще можете это сделать (читайте дальше вниз по странице, на которую я ссылался), но ваша цель кажется "проще" или "менее странной". Я бы сказал, что метод, который вы считаете странным, на самом деле самый простой, самый нормальный.

...