Can I create an new instance of my custom managed object class without going through NSEntityDescription?
From an Apple example, I have this:
Event *event = (Event*)[NSEntityDescription
insertNewObjectForEntityForName:@"Event"
inManagedObjectContext:self.managedObjectContext];
Event
inherits from NSManagedObject
. Is there a way to avoid this weird call to NSEntityDescription and instead just alloc+init
somehow directly the Event
class? Would I have to write my own initializer that just does that stuff above? Or is NSManage开发者_JS百科dObject
already intelligent enough to do that?
NSManagedObject
provides a method called initWithEntity:insertIntoManagedObjectContext:
. You can use this to do a more traditional alloc
/init
pair. Keep in mind that the object this returns is not autoreleased.
I've run into the exact same problem. It turns out you can completely create an entity and not add it to the store at first, then make some checks on it and if everything is good insert it into the store. I use it during an XML parsing session where I only want to insert entities once they have been properly and entirely parsed.
First you need to create the entity:
// 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];
Then once you are happy with the processing you can simply insert your entity into the store:
[self managedContext] insertObject:currentEntity
Note that in those examples the currentEntity object has been defined in a header file as follows:
id currentEntity
To get it to work properly, there is a LOT of stuff to do. -insertNewObject:... is by far the easiest way, weird or not. The documentation says:
A managed object differs from other objects in three main ways—a managed object ... Exists in an environment defined by its managed object context ... there is therefore a lot of work to do to create a new managed object and properly integrate it into the Core Data infrastructure ... you are discouraged from overriding initWithEntity:insertIntoManagedObjectContext:
That said, you can still do it (read further down the page to which I linked) but your goal appears to be "easier" or "less weird". I'd say the method you feel is weird is actually the simplest, most normal way.
I found a definitive answer from More iPhone 3 Development by Dave Mark and Jeff LeMarche.
If it really bothers you that you use a method on NSEntityDescrpiton
rather than on NSManagedObjectContext
to insert a new object into an NSManagedObjectContext
, you can use a category to add an instance method to NSManagedObjectContext
.
Create two new text files called NSManagedObject-Insert.h and NSManagedObject-Insert.m.
In NSManagedObject-Insert.h, place the following code:
import <Cocoa/Cocoa.h>
@interface NSManagedObjectContext (insert)
- (NSManagedObject *)insertNewEntityWithName:(NSString *)name;
@end
In NSManagedObject-Insert.m, place this code:
#import "NSManagedObjectContext-insert.h"
@implementation NSManagedObjectContext (insert)
- (NSManagedObject *)insertNewEntityWithName:(NSString *)name
{
return [NSEntityDescription insertNewObjectForEntityForName:name inManagedObjectContext:self];
}
@end
You can import NSManagedObject-Insert.h anywhere you wish to use this new method. Then replace the insert calls against NSEntityDescription
, like this one:
NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
with the shorter and more intuitive one:
[context insertNewEntityWithName:[entity name]];
Aren't categories grand?
精彩评论