Pro Core Data book, example code question
I'm learning Core Data with the help of the book. There is a code:
- (void)loadData {
// Pull the movies. If we have 200, assume our db is set up.
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Movie"
inManagedObjectContext:context]];
NSArray *results = [context executeFetchRequest:request error:nil];
if ([results count] != 200) {
// Add 200 actors, movies, and studios
for (int i = 1; i <= 200; i++) {
[self insertObjectForName:@"Actor" withName:
[NSString stringWithFormat: @"Actor %d", i]];
[self insertObjectForName:@"Movie" withName:
[NSString stringWithFormat: @"Movie %d", i]];
[self insertObjectForName:@"Studio" withName:
[NSString stringWithFormat: @"Studio %d", i]];
}
// Relate all the actors and all the studios to all the movies
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *request = [[NSFet开发者_运维知识库chRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:@"Movie"
inManagedObjectContext:context]];
NSArray *results = [context executeFetchRequest:request error:nil];
for (NSManagedObject *movie in results) {
[request setEntity:[NSEntityDescription entityForName:@"Actor"
inManagedObjectContext:context]];
NSArray *actors = [context executeFetchRequest:request error:nil];
NSMutableSet *set = [movie mutableSetValueForKey:@"actors"];
[set addObjectsFromArray:actors];
[request setEntity:[NSEntityDescription entityForName:@"Studio"
inManagedObjectContext:context]];
NSArray *studios = [context executeFetchRequest:request error:nil];
set = [movie mutableSetValueForKey:@"studios"];
[set addObjectsFromArray:studios];
}
}
[request release];
NSError *error = nil;
if (![context save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
The main question is: is it necessary to renew the context pointer, if there were any changes in that context? What I mean: I get the pointer to the context at the beginning of the method, next in the loop I take this context and insert managed objects there (-insertObjectForName:withName:). Then I see this renewal of the context pointer and have that question: is it a rule of some kind, and I should act the same, or its just not-so-neat code example? Why can't I use the old pointer?
---Edit--- One more question: is that a legal initialization of a request here in the code:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
...
NSFetchRequest *request = [[NSFetchRequest alloc] init];
...
[request release];
Two allocs and only one release?
I also have this book and looked it up.
Clearly seems like a typo to me and doesn't really make much sense.
Just ignore that line and continue - it should work fine without.
In my opinion
its just not-so-neat code example
About your second question: There have to also two releases! Otherwise you have a leak.
That's some seriously ugly code.
This:
NSManagedObjectContext *context = [self managedObjectContext];
... is probably just because they want to be able to write context
in a method call instead of self.managedObjectContext
.
Using: NSFetchRequest *request = [[NSFetchRequest alloc] init];
... twice is allowed but it is lazy bad practice. Any variable should be named only once in a scope. In fact, the compiler will generate a warning with this code. It will leak because every init
must be balanced by a release
.
精彩评论