Настраиваемые инициализаторы и свойства только для чтения в Core Data - PullRequest
3 голосов
/ 02 ноября 2009

До работы с Objective-C и Core Data у меня были случаи создания классов, которые нужно было инициализировать с определенными параметрами, которые после инициализации не могли быть изменены (хотя их можно было прочитать).

Я полагаю, что с Core Data я могу создать настраиваемый init для моего производного класса 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? Есть ли лучший способ, о котором я не думаю?

Спасибо!

Ответы [ 2 ]

1 голос
/ 02 ноября 2009

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

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

0 голосов
/ 15 мая 2013

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

-(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;
}

Документация insertNewObjectForEntityForName:inManagedObjectContext: NSEntityDescription говорит, что это примерно то, как он преобразуется из заданного entityName (@ "Cell") и контекста (из ownerCellList) в NSManagedObject экземпляр.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...