我正在将现有的Core Data应用程序修改为iCloud。我的问题是,当我在appDelegate中检测到初始应用程序启动后尝试加载种子数据时,我的第一个[NSEntityDescription insertNewObjectForEntityForName: inManagedObjectContext:]
语句抛出错误“'NSInvalidArgumentException',原因:'+ entityForName:XXX nil不是合法的NSManagedObjectContext参数搜索实体名称'XXX''“我确定我传递的inManagedObjectContext参数是正确的,但果然,它在调试器中是零。
我的部分麻烦在于我不明白应用程序调用样板核心数据-managedObjectContext,-managedObjectModel和-persistentStoreCoordinators方法的原因。应用程序似乎总是调用方法并在需要时自动实例化这些对象。
核心数据堆栈基本上是核心数据应用程序模板的标准内容,iCloud选项添加到persistentStoreCoordinator,以及用于迁移现有数据的分支。这是代码;试图将其限制为基本要素:
@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Notification registrations
[self register_iCloudNotifications];
// Data from defaults
BOOL _firstLocalLaunch = ...
BOOL _update =
BOOL _iCLoudDataSeeded = ...
// FIRST APP LAUNCH LOCALLY; FIRST iCLOUD LAUNCH ANYWHERE
// This is the code that's calling initializeSeedData and getting the error
if (_firstLocalLaunch && !_iCloudDataSeeded) {
[self initializeSeedData];
... update defaults
} else if {
... code for update launch and normal launch
// Safety check for seed data in persistent store; if none, initialize.
NSFetchRequest *modelFetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *modelEntity = [NSEntityDescription entityForName:@"entity" inManagedObjectContext:self.managedObjectContext];
[modelFetchRequest setEntity:modelEntity];
NSArray *fetchResults = [_managedObjectContext executeFetchRequest:modelFetchRequest error:nil];
if (!fetchResults.count) {
NSLog(@"Safety catch: seed data missing");
[self initializeSeedData];
}
return YES;
}
- (void)initializeSeedData
{
SWSEntity *entity1 = [NSEntityDescription insertNewObjectForEntityForName:@"Entity" inManagedObjectContext:_managedObjectContext]; // THIS IS WHATS THROWING THE ERROR
entity.name = @"First seed data item";
[_managedObjectContext save:nil];
}
- (NSManagedObjectContext *)managedObjectContext
{
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return _managedObjectContext;
}
- (NSManagedObjectModel *)managedObjectModel
{
if (_managedObjectModel != nil) {
return _managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"model" withExtension:@"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (_persistentStoreCoordinator != nil) {
NSLog(@"exists; returning");
return _persistentStoreCoordinator;
}
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
// NO UPDATE FROM PREVIOUS
if (!_update) {
NSLog(@"Persistent store: adding");
[self add_iCloudPersistentStore];
// UPDATE FROM PREVIOUS VERSION
} else {
NSLog(@"Persistent store: migrating");
...code for migrating existing store to iCloud; not called with this issue
}
return _persistentStoreCoordinator;
}
- (void)add_iCloudPersistentStore
{
NSError *error = nil;
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:[self get_iCloudStoreURL]
options:[self iCloudPersistentStoreOptions]
error:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
}
- (NSDictionary *)iCloudPersistentStoreOptions
{
return @{NSPersistentStoreUbiquitousContentNameKey: @"myAppStore",
NSMigratePersistentStoresAutomaticallyOption : @YES,
NSInferMappingModelAutomaticallyOption : @YES};
}
有趣的事情:如果我在检测到第一次启动后注释掉[self initializeSeedData],则执行添加数据的“安全捕获”,并创建种子数据就好了!我能想到的唯一不同之处在于我首先在托管对象上下文中执行fetchRequest ...不知何故,_managedObjectContext在执行fetch时被实例化,并且仍然围绕[self initializeSedData]。为什么会这样?