在本文开始,先给出反向工程后的结果:
在AppDelegate类中定义了下面三个属性:
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext; @property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel; @property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
现在我们希望搞清楚他们分别都有什么作用。所以看看有关 managedObjectContext 的代码:
- (void)saveContext { NSError *error = nil; NSManagedObjectContext *managedObjectContext = self.managedObjectContext; if (managedObjectContext != nil) { if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) { // Replace this implementation with code to handle the error appropriately. // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } } }
现在我们可以知道,managedObjectContext是一个处理数据库操作的操作环境。在设计模式中会时常看到上下文环境这样一个角色,这个角色模拟一个操作系统,负责与客户端对象进行交互,换句话说,一个Context类中的代码以及它的实例字段,告诉了线程要如何执行全局性的指令。
我们进一步看managedObjectContext 的 setter、getter方法:
- (NSManagedObjectContext *)managedObjectContext { if (_managedObjectContext != nil) { return _managedObjectContext; } NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; if (coordinator != nil) { _managedObjectContext = [[NSManagedObjectContext alloc] init]; [_managedObjectContext setPersistentStoreCoordinator:coordinator]; } return _managedObjectContext; }
这说明,一个managedObjectContext 拥有一个 persistentStoreCoordinator 的引用。
我们再来看 persistentStoreCoordinator 的相关代码:
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator { if (_persistentStoreCoordinator != nil) { return _persistentStoreCoordinator; } NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Persistence_CoreData.sqlite"]; NSError *error = nil; _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); abort(); } return _persistentStoreCoordinator; }
这说明,一个 persistentStoreCoordinator 对象(内存块)将按照一个 managedObjectModel来初始化,同时需要知道 *.sqlite 文件中的内容。我们知道 *.sqlite 是数据库文件,那么我们猜想 persistentStoreCoordinator 是一个关系实例,或者说它拥有关系实例的引用。我们猜想 managedObjectModel 对象定义了应用需要的关系模式,因此 persistentStoreCoordinator 需要它。
- (NSManagedObjectModel *)managedObjectModel { if (_managedObjectModel != nil) { return _managedObjectModel; } NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Persistence_CoreData" withExtension:@"momd"]; _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; return _managedObjectModel; }
上述代码说明,managedObjectModel 拥有一个 *.momd文件,我们知道这是我们定义CoreData数据模型使用的文件,因此更确定了 managedObjectModel 定义关系模式的观点。
ps:
关系模式和关系实例之间,类似于类与对象的关系。一个关系模式定义了一个关系实例需要有的字段以及各种约束,它定义了无数个关系实例的集合。
ps:
这是一个对象关系模型 ORM,每个查询都对应一个内存块(对象)fetchRequest,可以设置SQL语句中的每个语句块。