如何将Core Data添加到现有项目?

时间:2022-06-29 10:57:41

I am currently working though this tutorial, that explains how to add Core Data to an existing project.

我目前正在学习本教程,该教程解释了如何将Core Data添加到现有项目中。

I am up to the part titled

我是标题的部分

AppDelegate.m

It says this:

它说:

Implement applicationDocumentsDirectory, and explicitly write accessor methods for each new property as opposed to simply using the @synthesize keyword. Note in the persistentStoreCoordinator accessor there is a location where you must name the SQLite file used for the store; this should most likely be your project name. Remember to properly release each object in dealloc:

实现applicationDocumentsDirectory,并为每个新属性显式编写访问器方法,而不是简单地使用@synthesize关键字。请注意,在persistentStoreCoordinator访问器中,您必须指定用于存储的SQLite文件的位置;这很可能是你的项目名称。记得在dealloc中正确释放每个对象:

I do not understand what this part is asking me to do

我不明白这部分要求我做什么

Implement applicationDocumentsDirectory, and explicitly write accessor methods for each new property as opposed to simply using the @synthesize keyword.

实现applicationDocumentsDirectory,并为每个新属性显式编写访问器方法,而不是简单地使用@synthesize关键字。

From what I can tell its asking me to implement the variables differently from how I normally do them with the @synthesize.. but im not sure how else to do it...if someone could help me out that would be awesome.

从我可以告诉它要求我实现变量与我通常使用@synthesize的方式不同...但我不知道如何做到这一点...如果有人可以帮助我那将是非常棒的。

Here is my property code

这是我的房产代码

//Core Data
@property (nonatomic, strong, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, strong, readonly) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, strong, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;

3 个解决方案

#1


3  

I think what that particular paragraph is saying is that you need to create custom getters for your CoreData ivars.

我认为那个特定段落的含义是你需要为你的CoreData ivars创建自定义getter。

For instance, if you look at a fresh new template project created by Xcode, you will notice that all of the CoreData properties have their custom getters set, and they lazily instantiate/create the ivars the first time you access them.

例如,如果您查看由Xcode创建的全新模板项目,您会注意到所有CoreData属性都设置了自定义getter,并且在您第一次访问它们时它们会懒惰地实例化/创建ivars。

For instance, the method below checks if your managedObjectContext ivar is not nil, in which case the context has already been created so the getter method will simply return it to the calling method (which is typically you accessing the managedObjectContext property with self.managedObjectProperty)

例如,下面的方法检查您的managedObjectContext ivar是否不是nil,在这种情况下已经创建了上下文,因此getter方法将简单地将其返回给调用方法(通常使用self.managedObjectProperty访问managedObjectContext属性)

- (NSManagedObjectContext*)managedObjectContext
{
    if (_managedObjectContext != nil)
       return _managedObjectContext
    _managedObjectContext = ...
}

The applicationsDocumentDirectory method is just a convenience method that returns the path to the documents directory which will then be used by your persistent store coordinator to set the path for your CoreData database file.

applicationsDocumentDirectory方法只是一种方便的方法,它返回文档目录的路径,然后持久性存储协调器将使用该路径来设置CoreData数据库文件的路径。

Your best bet is to create a new project and copy the entire CoreData stack from the AppDelegate onto your existing project. You will then need to create a managed object model and make sure you have set the name correctly in the NSManagedObjectModel method, then you should be good to go.

最好的办法是创建一个新项目,并将整个CoreData堆栈从AppDelegate复制到现有项目中。然后,您需要创建一个托管对象模型,并确保在NSManagedObjectModel方法中正确设置了名称,然后您应该好好去。

#2


3  

You can clean up the template Core Data code a lot. The references to NSPersistentStoreCoordinator and NSManagedObjectModel are not needed. I tend to roll up all three into a single method to make the code a little more concise.

您可以大量清理模板Core Data代码。不需要对NSPersistentStoreCoordinator和NSManagedObjectModel的引用。我倾向于将所有三个汇总到一个方法中,以使代码更简洁。

@interface AppDelegate()

@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;

@implementation AppDelegate

@synthesize managedObjectContext = $managedObjectContext;

- (NSManagedObjectContext *)managedObjectContext
{
  if ($managedObjectContext) return $managedObjectContext;

  NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Example" withExtension:@"momd"];
  NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
  NSAssert1(mom, @"%@:%@ No model to generate a store from", [self class], NSStringFromSelector(_cmd));

  NSFileManager *fileManager = [NSFileManager defaultManager];
  NSURL *libraryURL = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
  NSURL *url = [libraryURL URLByAppendingPathComponent:@"Example.storedata"];
  NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
  NSAssert(coordinator, @"Failed to initialize coordinator");

  NAssert1([coordinator addPersistentStoreWithType:NSXMLStoreType configuration:nil URL:url options:nil error:&error], @"Error: %@", error);

  $managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
  [$managedObjectContext setPersistentStoreCoordinator:coordinator];

  return $managedObjectContext;
}

With that code you have a class continuation that handles the ivar. We use a synthesize so that we can talk directly to the ivar in the get accessor.

使用该代码,您可以使用处理ivar的类继续。我们使用合成,以便我们可以直接与get访问器中的ivar对话。

Since the MOM and PSC can be accessed via the MOC there is no need to keep extra references to them around.

由于可以通过MOC访问MOM和PSC,因此无需对它们进行额外的引用。

#3


1  

Even with @property declarations, you can still implement the accessors however you like.

即使使用@property声明,您仍然可以实现您喜欢的访问器。

- (NSString *)applicationDocumentsDirectory {
    return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}

#1


3  

I think what that particular paragraph is saying is that you need to create custom getters for your CoreData ivars.

我认为那个特定段落的含义是你需要为你的CoreData ivars创建自定义getter。

For instance, if you look at a fresh new template project created by Xcode, you will notice that all of the CoreData properties have their custom getters set, and they lazily instantiate/create the ivars the first time you access them.

例如,如果您查看由Xcode创建的全新模板项目,您会注意到所有CoreData属性都设置了自定义getter,并且在您第一次访问它们时它们会懒惰地实例化/创建ivars。

For instance, the method below checks if your managedObjectContext ivar is not nil, in which case the context has already been created so the getter method will simply return it to the calling method (which is typically you accessing the managedObjectContext property with self.managedObjectProperty)

例如,下面的方法检查您的managedObjectContext ivar是否不是nil,在这种情况下已经创建了上下文,因此getter方法将简单地将其返回给调用方法(通常使用self.managedObjectProperty访问managedObjectContext属性)

- (NSManagedObjectContext*)managedObjectContext
{
    if (_managedObjectContext != nil)
       return _managedObjectContext
    _managedObjectContext = ...
}

The applicationsDocumentDirectory method is just a convenience method that returns the path to the documents directory which will then be used by your persistent store coordinator to set the path for your CoreData database file.

applicationsDocumentDirectory方法只是一种方便的方法,它返回文档目录的路径,然后持久性存储协调器将使用该路径来设置CoreData数据库文件的路径。

Your best bet is to create a new project and copy the entire CoreData stack from the AppDelegate onto your existing project. You will then need to create a managed object model and make sure you have set the name correctly in the NSManagedObjectModel method, then you should be good to go.

最好的办法是创建一个新项目,并将整个CoreData堆栈从AppDelegate复制到现有项目中。然后,您需要创建一个托管对象模型,并确保在NSManagedObjectModel方法中正确设置了名称,然后您应该好好去。

#2


3  

You can clean up the template Core Data code a lot. The references to NSPersistentStoreCoordinator and NSManagedObjectModel are not needed. I tend to roll up all three into a single method to make the code a little more concise.

您可以大量清理模板Core Data代码。不需要对NSPersistentStoreCoordinator和NSManagedObjectModel的引用。我倾向于将所有三个汇总到一个方法中,以使代码更简洁。

@interface AppDelegate()

@property (nonatomic, retain) NSManagedObjectContext *managedObjectContext;

@implementation AppDelegate

@synthesize managedObjectContext = $managedObjectContext;

- (NSManagedObjectContext *)managedObjectContext
{
  if ($managedObjectContext) return $managedObjectContext;

  NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Example" withExtension:@"momd"];
  NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
  NSAssert1(mom, @"%@:%@ No model to generate a store from", [self class], NSStringFromSelector(_cmd));

  NSFileManager *fileManager = [NSFileManager defaultManager];
  NSURL *libraryURL = [[fileManager URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
  NSURL *url = [libraryURL URLByAppendingPathComponent:@"Example.storedata"];
  NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
  NSAssert(coordinator, @"Failed to initialize coordinator");

  NAssert1([coordinator addPersistentStoreWithType:NSXMLStoreType configuration:nil URL:url options:nil error:&error], @"Error: %@", error);

  $managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
  [$managedObjectContext setPersistentStoreCoordinator:coordinator];

  return $managedObjectContext;
}

With that code you have a class continuation that handles the ivar. We use a synthesize so that we can talk directly to the ivar in the get accessor.

使用该代码,您可以使用处理ivar的类继续。我们使用合成,以便我们可以直接与get访问器中的ivar对话。

Since the MOM and PSC can be accessed via the MOC there is no need to keep extra references to them around.

由于可以通过MOC访问MOM和PSC,因此无需对它们进行额外的引用。

#3


1  

Even with @property declarations, you can still implement the accessors however you like.

即使使用@property声明,您仍然可以实现您喜欢的访问器。

- (NSString *)applicationDocumentsDirectory {
    return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}