Customized initializers and read only properties in Core Data
Before working with Objective-C and Core开发者_开发百科 Data, I had occasions to create classes that needed to be initialized with certain parameters that, after initialization, could not be modified (though they could be read).
With Core Data, I believe I can create a customized init on my NSManagedObject derived class as long as it includes a way to insert the object into a context like such:
-(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;
}
Normally, I'd have a location variable and the location property would be read-only (so once set at initialization, it could not be changed). Is there a way to get this sort of pattern with Core Data? Is there a better way I'm not thinking of?
Thanks!
You are correct. As long as your initializer calls the NSManagedObject
's designated initializer, your approach is fine. You can also override the -[NSManagedObject awakeFromInsert]
to perform some action after insertion (creation) or -[NSManagedObject awakeFromFetch]
to perform an action (e.g. populating a cache) each time the object is faulted back into a managed object context.
Like the rest of Objective-C, there is no way to make a property truly readonly. Malicious code will likely be able to modify your property. However, in your custom class, you can declare a @property(readonly)
for e.g. location
. This will at least cause a warning if you try to modify the property and will signal your intent to client code.
For anyone who stumbles here, reads the comments, and wonders at the final answer, it should be something like this. Continuing with the example above, it would be:
-(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's insertNewObjectForEntityForName:inManagedObjectContext:
documentation says this is roughly how it converts from a given entityName (@"Cell") and a context (from ownerCellList
) to an NSManagedObject
instance.
精彩评论