2

我从以下代码中得到一个令人讨厌的模糊错误:

GFree2AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
context = [delegate managedObjectContext];

context在 .h 文件中被定义为 aNSManagedObjectContext并且在委托中是相同的。似乎包含了所有正确的文件(除了<CoreData/CoreData.h>.m 文件 - 但无论是否包含,程序都会引发相同的问题。它包含在头文件中。)

包括所有正确的框架和东西——当我开始项目时,我选择了“使用 coredata 来管理数据”或其他任何东西。那么肯定不应该有问题吗?

有没有更好的方法来做我想做的事情?基本上我不想一直通过不同的类传递上下文,直到我最终想要使用它(存储数据是我应用程序的一小部分)。

在控制台中,我得到的错误是:

    2010-08-28 13:09:24.726 GFree2[3912:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSURL initFileURLWithPath:]: nil string parameter'
...

    terminate called after throwing an instance of 'NSException'
    Program received signal:  “SIGABRT”.

如果我注释掉这条线:context = [delegate managedObjectContext];那么一切似乎都很好。(目前我还没有实际使用任何 coredata 或任何东西,所以没有更多与之相关的代码。

感谢任何可以提供帮助或对此提供一些见解的人 - 它是如此复杂。

编辑:我的应用委托文件方法:

#pragma mark -
#pragma mark Core Data stack

/**
 Returns the managed object context for the application.
 If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application.
 */
- (NSManagedObjectContext *)managedObjectContext {

  if (managedObjectContext != nil) {
    return managedObjectContext;
  }

  NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
  if (coordinator != nil) {
    managedObjectContext = [[NSManagedObjectContext alloc] init];
    [managedObjectContext setPersistentStoreCoordinator:coordinator];
  }
  return managedObjectContext;
}


/**
 Returns the managed object model for the application.
 If the model doesn't already exist, it is created from the application's model.
 */
- (NSManagedObjectModel *)managedObjectModel {
  if (managedObjectModel != nil) {
    return managedObjectModel;
  }

  NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"GFree" ofType:@"momd"];
  NSURL *modelURL = [NSURL fileURLWithPath:modelPath];
  managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];    
  return managedObjectModel;
}

/**
 Returns the persistent store coordinator for the application.
 If the coordinator doesn't already exist, it is created and the application's store added to it.
 */
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
  if (persistentStoreCoordinator != nil) {
    return persistentStoreCoordinator;
  }

  NSURL *storeURL = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"GFree.sqlite"]];

  NSError *error = nil;
  persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
  if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&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. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.

      Typical reasons for an error here include:
        * The persistent store is not accessible;
        * The schema for the persistent store is incompatible with current managed object model.

      Check the error message to determine what the actual problem was.

      If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory.

      If you encounter schema incompatibility errors during development, you can reduce their frequency by:
        * Simply deleting the existing store:
          [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil]

        * Performing automatic lightweight migration by passing the following dictionary as the options parameter: 
          [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

        Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details.

    */
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
  }    

  return persistentStoreCoordinator;
}

#pragma mark -
#pragma mark Application's Documents directory

/**
 Returns the path to the application's Documents directory.
 */
- (NSString *)applicationDocumentsDirectory {
  return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}

再次编辑:

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"GFree" ofType:@"momd"];
    NSURL *modelURL = [NSURL fileURLWithPath:modelPath];

是错误所在的行。我不确定这是什么类型的文件,但我确定它显然没有找到它或其他东西......:/我应该做什么的任何想法?

@kiamlaluno - 很抱歉回滚你的编辑,不是故意的,只是想看看你改变了什么,并认为这会告诉我......但它显然完全删除了它们。哈哈。

编辑构建结果:

DataModelCompile build/Debug-iphonesimulator/GFree2.app/GFree2.mom GFree2.xcdatamodel
cd "/Volumes/files/Gluten Free Cooking/Tom iPhone App/GFree2"
setenv PATH "/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin"
/Developer/usr/bin/momc -XD_MOMC_TARGET_VERSION=10.6 "/Volumes/files/Gluten Free Cooking/Tom iPhone App/GFree2/GFree2.xcdatamodel" "/Volumes/files/Gluten Free Cooking/Tom iPhone App/GFree2/build/Debug-iphonesimulator/GFree2.app/GFree2.mom"
4

2 回答 2

1

我相信问题出persistentStoreCoordinator在您GFree2AppDelegate.m文件中的方法上。

你能用这个文件中的确切代码和managedObjectModel方法更新你的问题吗?managedObjectContextpersistentStoreCoordinator

当您选中“使用核心数据进行存储”时,这些方法由 XCode 生成。

顺便说一句,您不应该导入 .m 文件。

于 2010-08-28T12:39:04.987 回答
1

您收到错误是因为 GFree.momd 不存在。来自 NSURL 的 pathForResource:ofType: 方法的文档:

返回值资源文件的完整路径名,如果找不到文件,则返回 nil。

GFree.momd 是在构建时从您的 .xcdatamodeld 文件生成的(在构建结果中查找以 DataModelVersionCompile 开头的行并展开它)。您是否删除或重命名了该文件?

它是否仍然列在构建目标的编译源部分中?(在 Xcode 中展开 Targets / [AppName] / Compile Sources)。

刚刚注意到您的调试日志显示该应用程序名为 GFree2,但您的代码正在寻找 GFree.momd。您是否重命名了项目?如果数据模型文件现在称为 GFree2.xcdatamodeld,那么您也需要更改导入 momd 文件的行以使用新的 GFree2 名称。

于 2010-08-28T16:09:35.760 回答