enter image description here

正在研究iOS中Core Data框架,所以尝试翻译了一下MoreiPhoneDevelopment这本书中的CoreData部分,也算不上翻译,只是按照自己学习的理解写下来的,英文能力和技术水平有限,所以很多有纰漏的地方希望大家一起探讨、学习。有时间我会持续更新,希望大家一起学习进步,另外祝贺图灵新社区上线,让我们有了一片可以交流的园地!

Core Data is a framework and set of tools that allow you to persist your application’s data to the iPhone’s file system automatically. Core Data is a form of something called object-relational mapping, or ORM, which is just a fancy way of saying that Core Data takes the data stored in your Objective-C objects and translates (or maps) that data into another form so that it can be easily stored in a database, such as SQLite, or into a flat file.

CoreData 是一个在iOS系统中自动的为你保存应用程序相关数据的框架和一套工具。CoreData是对象-关系-映射或者叫做ORM的一种表现形式,以一种特别的方式把数据存储在Objective-C对象中并把他们翻译(映射)到另一种形式, 这样就可以轻松的保存到类似SQLite数据库,或者是普通文件中。

Core Data can seem like magic when you first start using it. Objects are simply dealt with as objects, and they seem to know how to save themselves into the database or file system. You won’t create SQL strings or make file management calls—ever. Core Data insulates you from some complex and difficult programming tasks, which is great for you. By using Core Data, you can develop applications with complex data models much, much faster than you could using straight SQLite, object archiving, or flat files.

当你第一次开始用CoreData框架时,会觉得它比较神奇。对象就是简单的被当做对象处理,而且它们好像自己就知道如何将自己存储到数据库或者文件中。你不用写SQL语句或者是调用文件管理器。CoreData使你不再纠结于复杂的代码,这对你非常的方便。使用CoreData框架你可以使用复杂的数据模型来开发应用程序,这比直接使用SQLite数据库或者运用对象归档或者将数据存储到文件中要更加高效!

Technologies that hide complexity the way Core Data does can encourage “voodoo programming”—that most dangerous of programming practices where you include code in your application that you don’t necessarily understand. Sometimes, that mystery code arrives in the form of a project template. Or, perhaps, you downloaded a utilities library that did a task for you that you just don’t have the time or expertise to do for yourself. That voodoo code does what you need it to do, and you don’t have the time or inclination to step through it and figure it out, so it just sits there, working its magic … until it breaks. Though this is not always the case, as a general rule, if you find yourself with code in your own application that you don’t fully understand, it’s a sign you should go do a little research, or at least find a more experienced peer to help you get a handle on your mystery code.

一种最危险的编程实践,是在你的应用程序中出现了一些你并不一定明白的代码。 有时候项目模板中会出现一些令人难以理解的神秘代码。你可能会下载一些工具库来帮助你解决那些你没有时间或者不懂的技术难题。因为你没有时间或者没有兴趣一步步的调试或者把代码弄明白,VOODOO Code就是你需要做的,因为代码就在那里执行,直到它退出。虽然不是常常如此,但是一般来说,如果在你的应用程序中找到了一些你不是完全理解的代码,你就需要做一些工作,或者至少是找到有经验的同事来帮助你解决那些神秘的代码。

The point is that Core Data is one of those complex technologies that can easily turn into a source of mystery code that will make its way into many of your projects. Although you don’t need to know exactly how Core Data accomplishes everything it does, you should invest some time and effort into understanding the overall Core Data architecture.

有一点值得注意的就是,CoreData是一种可以让你在你的大多数项目中轻松使用的复杂技术。尽管你没有必要去了解CoreData如何完成的,但是你也应该抽出点实践和精力,并加以努力去了解CoreData框架的整体结构。

In this chapter, we’ll start with a brief history of Core Data, and then dive into the Core Data template itself. By dissecting Xcode’s default Core Data template, you’ll find it much easier to understand the more complex Core Data projects we get into in the following chapters.

在这章里,我们将会简短的介绍CoreData的历史,并且将深入到CoreData项目模板中。通过剖析Xcode中默认的CoreData模板,你将会意识到CoreData项目很容易理解,让我们进入这章。

A Brief History of Core Data

Core Data has been around for quite some time, but it just became available on the iPhone with the release of iPhone SDK 3.0. Core Data was originally introduced with Mac OS X 10.4 (Tiger), but some of the DNA in Core Data actually goes back about 15 years, to a NeXT framework called Enterprise Objects Framework (EOF), part of NeXT’s WebObjects web development tool set.

CoreData出现了很长一段时间了,但是直到iPhone SDK3.0发布的时候才被融入iPhone中。虽然CoreData是在Mac OS X10.4(Tiger)的时候才出现的,但是其中的一部分是遗传自15年前的NeXT公司一套NeXT's WebObjects web开发工具中的一个叫做Enterprise Objects Framework (EOF)的框架。

EOF was designed to work with remote databases, and it was a pretty revolutionary tool when it first came out. Although there are now many good ORM tools for almost every language, when WebObjects was in its infancy, most web applications were written to use handcrafted SQL or file system calls to persist their data. Back then, writing web applications was incredibly time- and labor-intensive. WebObjects, in part because of EOF, cut the development time needed to create complex web applications by an order of magnitude.

EOF是一套操作远程数据库的工具,当它第一次出现的时候被认为具有相当大的革命性。尽然现在每一种变成语言都拥有了属于自己的ORM工具,但是在WebObjects初期,大多数网络应用程序都是靠着手写SQL语句或者是文件系统调用来保存数据的。那时,编写网络应用不仅需要大量的时间,而且还消耗着大量的劳力。WebObjects,部分原因是由于EOF,大量削减了编写复杂的网络应用的开发时间。

In addition to being part of WebObjects, EOF was also used by NeXTSTEP, which was the predecessor to Cocoa. When Apple bought NeXT, the Apple developers used many of the concepts from EOF to develop a new persistence tool called Core Data. Core Data does for desktop applications what EOF had previously done for web applications: It dramatically increases developer productivity by removing the need to write file system code or interact with an embedded database.

除了作为WebObjects的一部分以外,EOF框架还被称作NeXTSTEP,NeXTSTEP是Cocoa框架的前辈。在苹果公司收购了NeXT以后,苹果公司的开发工程师们运用了大量的EOF思想开发出一套新的持久层工具,叫做CoreData。CoreData框架用EOF以前为编写网络应用的结果来开发桌面应用程序。这比直接写入系统文件或者操作嵌入式数据库大大提高了开发人员的工作效率。

Let’s take a look at a Core Data Xcode template.

让我们看看Xcode中CoreData的项目模板

Creating a Core Data Template Application

创建一个CoreData模板应用程序

Fire up Xcode and select New Project… from the File menu, or press ....N. When the new project assistant comes up, select Application under the iPhone OS heading in the left column, and then select Navigation-based Application from the upper-right pane. In the lower-right pane, make sure the box labeled Use Core Data for storage is checked, as in Figure 2–1. That check box is how we tell Xcode to give us all the code and extra stuff we need to start using Core Data. Not all Xcode project templates have this option, but it’s available for both the Navigation-based Application and Window-based Application templates.

启动Xcode并在文件菜单中选择New Project,或者cammand+N,当新建项目选项出现后,在左侧导航栏选择iPhone OS下的Application后,在右侧的项目模板中选择Navigation-based Application。在下方的窗口中确保Use Core Data for storage选择框被选中,参考图2-1. 勾选了Use Core Data for storage就是告诉Xcode为我们生成CoreData项目模板生成代码和额外的一些东西。并不是所有的Xcode项目模板都有这个选项,只是出现在the Navigation-based Application and Window-basedApplication 模板中。 enter image description here 图2-1

Call your project CoreData. Now build and run the application. It will work fine in either the simulator or on a physical device. It should look something like Figure 2–2.

给新建的项目命名为CoreData。现在运行应用程序,它会在模拟器或者是物理设备上良好运行。看上去会像图2-2 enter image description here

If you press the plus icon in the upper-right corner, it will insert a new row into the table that shows the exact date and time the plus button was pressed. You can also use the Edit button to delete rows. Exciting, huh?

如果你按下右上角的+号键,会自动在表中创建附加着准确时间和日期信息的行。你也可以用Edit键来删除行。对嘛?

CAUTION: Early versions of the Core Data Navigation-based Application template had a small bug. If you deleted the last row, the application would crash. This was fixed in SDK 3.1.

注意:早期的Core Data Navigation-based Application模板存在着一个小bug,如果你删除了最后一行,则应用程序会崩溃,这个问题在SDK3.1中得到解决。

Under the hood of this simple application, a lot is happening. Think about it—without adding a single class, or any code to persist data to a file or interact with a database,pressing the plus button created an object, it with data, and saved it to a SQLite database created for us automatically. There’s plenty of free functionality here.Now that you’ve seen an application in action, let’s take a look at what’s going on behind the scenes.

看似简单的模板,却实行了大量操作。试想一下,没有创建一个类,甚至没有写下一行代码来使用文件或者数据库来保存数据,按下+号键创建了一个含有数据的对象并且为我们自动保存。这里面有大量的方法,你已经看见了应用程序的运行,现在我们来看看内部是如何工作的。

Core Data Concepts and Terminology Like most complex technologies, Core Data has its own terminology that can be a bit intimidating to newcomers. Let’s break down the mystery and get our arms around Core Data’s nomenclature. Figure 2–3 shows a simplified, high-level diagram of the Core Data architecture. Don’t expect it all to make sense now, but as we look at different pieces, you might want to refer back to the diagram to cement your understanding of how they fit together.

和其他复杂的技术一样,CoreData也有令初学者畏惧的专业术语。让我们打破这种神奇,来了解一下这些术语。 图2-3显示了CoreData框架的基本结构。不要期望现在能把所有的相关知识都弄明白,我们将会逐一的学习,在以后的学习过程中,你可能需要回顾这幅插图来巩固你对CoreData各个部分如何组合在一起工作的理解。 enter image description here

There are five key concepts to focus on here. As you proceed through this chapter, make sure you understand each of the following: .. Persistent store .. Data model .. Persistent store coordinator .. Managed object and managed object context .. Fetch request Once again, don’t let the names throw you. Follow along, and you’ll see how all these pieces fit together.

这里有五个关键概念,通过本章,确保你能理解每一项。 ..存储仓库 ..数据模型 ..存储仓库协调器 ..管理对象和管理对象上下文 ..提取请求 再一次,不要被这些名字所迷惑,随着逐步的深入学习,你将会了解到这些部分是如何组合在一起协调工作的。

The Data Model and Persistent Store The persistent store, which is sometimes referred to as a backing store, is where Core Data stores its data. By default on the iPhone, Core Data will use a SQLite database contained in your application’s documents folder as its persistent store. But this can be changed without impacting any of the other code you write by tweaking a single line of code. We’ll show you the actual line of code to change in a few moments.

存储仓库有时又被称为后背存储器,它是CoreData框架用来存储数据的。在iPhone的默认情况下,CoreData会使用被包含在你的应用程序文件夹中的SQLite数据库作为数据存储仓库。但是,这是可以改变的,而且不会影响任何其他代码。 一会儿将向你展示具体的代码。

CAUTION: Do not change the type of persistent store once you have posted your application to the App Store. If you must change it for any reason, you will need to write code to migrate data from the old persistent store to the new one, or else your users will lose all of their data— something that will likely make them quite unhappy.

注意:不要在你向AppStore提交了你的应用程序以后,改变存储仓库的类型。如果你有理由一定需要改变的话,你需要编写代码进行数据迁移,不然的话,你应用程序的用户将会丢失所有数据,这会令他们非常不高兴!

Every persistent store is associated with a single data model, which defines the types of data that the persistent store can store. If you expand the Resources folder in the Groups & Files pane in Xcode, you’ll see a file called CoreData.xcdatamodel. That file is the default data model for your project. The project template we chose gave us a single persistent store and an associated data model. Single-click CoreData.xcdatamodel now to bring up Xcode’s data model editor. Your editing pane in Xcode should now look like Figure 2–4. As you design your own applications, this is where you’ll build your application’s data model.

每一个存储仓库都和一个独立的数据模型联系在一起,该模型定义了可被存储在存储仓库中的数据类型。如果你打开Xcode左侧菜单栏中的Groups & Files下的Resources folder文件夹,会看见一个名为CoreData.xcdatamodel的文件。 这个文件是你项目的默认数据模型。我们选择的项目模板提供了一个存储仓库和一个相关联的数据模型。点击CoreData.xcdatamodel文件可以进入数据模型编辑器。现在你在Xcode中的编辑窗口应该类似于图2-4.如果你设计自己的应用程序,这也是你建立你自己的数据模型的地方。

In this chapter, we’ll explore the data model that comes with the template. In Chapter 3,we’ll actually use the editor to create a custom data model.

在这一章节中,我们会结合着模板来探索一下数据模型。在第三章,我们将会创建自定义的数据模型。

Take a look at the data model editor. Notice the single rounded rectangle in the middle of the editing window. That rectangle is known as an entity. In effect, an entity is like a class definition, wrapping your various data elements under a single umbrella. This particular entity has the name Event, and it features sections for Attributes and Relationships. There’s a single attribute, named timeStamp, and no relationships.

看一下数据模型编辑器,注意编辑器窗口中间的独立圆角长方形。这个圆角长方形被认为是实体,事实上,一个实体就是一个类的定义,将各种数据元素包含起来。这个特别的实体被命名为Event,它包含属性和关系两种特性。这里有只有一个属性,被称为timeStamp,并且没有关系特性。

Click off the entity rectangle. The title bar should turn a light pink. Click back on the entity, and it will turn blue, indicating the entity is selected.

点击实体的圆角长方形,标题栏会变成粉色,回点实体,标题栏会变为蓝色,标题实体被选中。

The entity was created as part of this template. If you use this template to create your own Core Data application, you get the Event entity for free. As you design your own data models, you’ll most likely delete the Event entity and create your own entities from scratch.

这个实体是作为模板的一部分被创建的。如果你应用这个模板来创建你自己的CoreData应用程序,这个Event实体将会自动被创建。如果你设计自己的数据模型,大多数情况下会删除这个Event实体,而重新创建自己的实体。

enter image description here

TheDataModelClass:NSManagedObjectModel Although you won’t typically access your application’s data model directly, you should be aware of the fact that there is an Objective-C class that represents the data model in memory. This class is called NSManagedObjectModel, and the template automatically creates an instance of NSManagedObjectModel based on the data model file in your project. Let’s take a look at the code that creates it now.

尽管你不会直接访问你的应用程序中的数据模型,但是你也应该知道有一个Objective-C类代表着内存中的数据模型。这个类是NSManagedObjectModel,并且模板会根据你项目中的数据模型来自动创建一个NSManagedObjectModel类的实力。现在让我们看一下已经创建的代码。

In your project window’s Groups & Files pane, open the Classes group and single-clickCoreDataAppDelegate.m. At the top of the editor pane, click the function menu to bring up a list of the methods in this class (see Figure 2–5). Select -managedObjectModel,which will take you to the method that creates the object model based on the CoreData.xcdatamodel file.

在你的项目中的左侧window’s & Files窗口,打开Classes group并且点击CoreDataAppDelegate.m,在编辑窗口顶部,点击方法菜单,会出现这个类中的方法列表(图2-5)。选择-managedObjectModel,将会展示根据CoreData.xcdatamodel文件所创建的对象模型的方法。

enter image description here

方法应该是这样: /** Returns the managed object model for the application. If the model doesn't already exist, it is created by merging all of the models found in the application bundle. */

  • (NSManagedObjectModel *)managedObjectModel {

    if (managedObjectModel != nil)

    {

    return managedObjectModel;

    }

    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];

    return managedObjectModel;

}

The first thing it does is check the instance variable managedObjectModel to see if it’s nil. This accessor method uses a form of lazy loading. The underlying instance variable doesn’t actually get instantiated until the first time the accessor method is called. For this reason, you should never, ever access managedObjectModel directly (except within the accessor method itself, of course). Always make sure to use the accessor methods. Otherwise, you could end up trying to make calls on an object that hasn’t been created yet.

第一件事就是需要坚持实例变量managedObjectModel是否为nil。这种访问采用了懒加载的一种方式。直到访问器第一次被调用,底层的实例变量才会被实例化。 因此,你永远不要直接访问managedObjectModel(当然除了访问器本身)。确保总是使用访问器方法。否则,你最终可能会试图使用一个尚未创建对象。

TIP: The data model class is called NSManagedObjectModel because, as you’ll see a little later in the chapter, instances of data in Core Data are called managed objects.

数据模型类之所以被称为NSManagedObjectModel,就像本章稍后你将会看到的,在CoreData中数据实例被称为managed objects

If managedObjectModel is nil, we’ll go get our data models. Remember how we said that a persistent store was associated with a single data model? Well, that’s true, but it doesn’t tell the whole story. You can combine multiple .xcdatamodel files into a single instance of NSManagedObjectModel, creating a single data model that combines all the entities from multiple files. This line of code takes any .xcdatamodel files that might be in your Xcode project and combines them together into a single instance of NSManagedObjectModel: managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];

如果managedObjectModel为nil,我们就需要创建我们自己的数据模型。还记得我们如何描述的一个存储仓库关联与一个数据模型的?对,就是这样,不过,它并没有说明全部问题。你可以将多个xcdatamodel文件组合成一个NSManagedObjectModel类的实例,可以联合多个文件的实体中来创建一个数据模型。这行代码需要项目中的xcdatamodel文件联合组成一个NSManagedObjectModel的实例:managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];