2009-11-02 1 views
3

Перед тем как работать с объектно-ориентированными и основными данными, мне приходилось создавать классы, которые необходимо было инициализировать с помощью определенных параметров, которые после инициализации не могли быть изменены (хотя они могут быть изменены читать).Индивидуальные инициализаторы и свойства только для чтения в базовых данных

с Core Data, я считаю, что может создать настраиваемые инициализации на моем NSManagedObject производного классе до тех пор, как она включает в себя способ вставить объект в контекст, как например:

-(Cell*) initWithOwner:(CellList*)ownerCellList andLocation:(int)initLocation 
{ 
    if (self = (Cell*) [NSEntityDescription insertNewObjectForEntityForName:@"Cell" 
         inManagedObjectContext:[ownerCellList managedObjectContext]]) 
    { 
     self.location = [NSNumber numberWithInt:initLocation]; 
     self.owner = ownerCellList; 
     [ownerCellList addCellListObject:self]; 
    } 
    return self; 
} 

Обычно, я иметь переменную местоположения, а свойство location будет доступно только для чтения (поэтому после инициализации оно не может быть изменено). Есть ли способ получить такой шаблон с помощью Core Data? Есть ли лучший способ, о котором я не думаю?

Спасибо!

ответ

1

Вы верны. Пока ваш инициализатор вызывает назначенный инициализатор NSManagedObject, ваш подход прекрасен. Вы также можете переопределить -[NSManagedObject awakeFromInsert] для выполнения некоторых действий после вставки (создания) или -[NSManagedObject awakeFromFetch] для выполнения действия (например, заполнения кеша) при каждом обращении объекта обратно в контекст управляемого объекта.

Как и все остальные объекты Objective-C, нет возможности сделать свойство действительно для чтения. Вредоносный код, скорее всего, сможет изменить вашу собственность. Однако в вашем пользовательском классе вы можете объявить @property(readonly), например. location. Это, по крайней мере, вызовет предупреждение, если вы попытаетесь изменить свойство и сообщите о своем намерении для кода клиента.

+0

Хм ... у меня возникла другая мысль/вопрос: с помощью указанной выше функции init мне нужно будет сделать [[Cell alloc] initWith ...], так как это не функция уровня класса. Разве это не так неправильно с объектом Core Data, который автоматически выпущен? Было бы более целесообразным заменить функцию initWith ... функцией класса, например createNewCellWithOwner: (CellList *) ownerCellList andLocation: (int) initLocation? Вызов insertNewObjectForEntityForName создает новый объект и, похоже, не входит в процедуру инициализации, верно? – FTLPhysicsGuy

+1

Я этого не заметил. Да, у вас возникает утечка памяти (из начального + выделения), и у вас появятся проблемы, потому что вы не сохраняете результат -inertNewObject ... Я бы использовал self = [self initWithEntity: entity inManagedObjectContext: [ ownerCellIst managedObjectContext]]. –

0

Для всех, кто спотыкается здесь, читает комментарии и задает окончательный ответ, это должно быть что-то вроде этого. Продолжая предыдущий пример, это было бы:

-(Cell*) initWithOwner:(CellList*)ownerCellList andLocation:(int)initLocation 
{ 
    NSManagedObjectContext *context = [ownerCellList managedObjectContext]; 
    NSManagedObjectModel *managedObjectModel = 
      [[context persistentStoreCoordinator] managedObjectModel]; 
    NSEntityDescription *entity = 
      [[managedObjectModel entitiesByName] objectForKey:@"Cell"]; 
    self = [self initWithEntity:entity inManagedObjectContext:context]; 
    if (self) 
    { 
     self.location = [NSNumber numberWithInt:initLocation]; 
     self.owner = ownerCellList; 
     [ownerCellList addCellListObject:self]; 
    } 
    return self; 
} 

NSEntityDescription'sinsertNewObjectForEntityForName:inManagedObjectContext: документация говорит, что это примерно, как она переходит из заданного EntityName (@ «Cell») и контекст (от ownerCellList) до NSManagedObject экземпляра.

Смежные вопросы