CoreData入门与深入理解
立即解锁
发布时间: 2025-08-26 00:35:57 阅读量: 1 订阅数: 5 


Core Data实战指南
# Core Data 入门与深入理解
## 1. 为现有项目添加 Core Data
在开发过程中,有时我们需要为现有的 iOS 应用添加 Core Data 功能。以下是具体的操作步骤:
### 1.1 添加 Core Data 框架
在 Objective - C 中,库被称为框架。要让现有应用使用 Core Data,需将其框架添加到项目中,具体步骤如下:
1. 在 Xcode 左侧选择项目,右侧会显示目标设置。
2. 选择第四个标签“Build Phases”,打开“Link Binary With Libraries”部分。
3. 点击该部分下方的“+”按钮,会显示可添加的框架列表。
4. 选择“CoreData.framework”,然后点击“Add”按钮。
5. (可选)将项目源列表中的“CoreData.framework”条目拖到“Frameworks”文件夹。
完成这些步骤后,“CoreData.framework”会显示在 Xcode 左侧,应用就能使用该框架的类而不会产生编译错误。
### 1.2 创建数据模型
所有 Core Data 应用都需要一个数据模型,它描述了框架要管理的所有实体。以下是创建数据模型的步骤:
1. 在 Xcode 菜单中选择“File > New > New File”,从 iOS Core Data 模板中选择“Data Model”类型。
2. 点击“Next”,将数据模型命名为“MyModel.xcdatamodeld”,然后点击“Save”。这将生成新的数据模型并在 Xcode 中打开。
3. 数据模型打开后,点击 Xcode 窗口底部的“Add Entity”按钮添加实体。
4. 选择一个实体,点击并按住“Add Entity”按钮右侧的“Add Attribute”按钮,从下拉菜单中选择属性类型(属性、关系或获取属性)。
5. 为了简单起见,创建一个名为“MyData”的实体,包含一个名为“myAttribute”的字符串类型属性。
### 1.3 初始化托管对象上下文
最后一步是初始化托管对象上下文、持久数据存储和对象模型。可以添加与创建项目时选择使用 Core Data 时 Xcode 生成的相同代码。
#### 1.3.1 DemoAppAppDelegate.h 文件
```objc
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
@interface DemoAppAppDelegate : UIResponder <UIApplicationDelegate> {
}
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) UINavigationController *navigationController;
@property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;
@end
```
#### 1.3.2 DemoAppAppDelegate.m 文件
```objc
#import "DemoAppAppDelegate.h"
@implementation DemoAppAppDelegate
@synthesize managedObjectContext=__managedObjectContext;
@synthesize managedObjectModel=__managedObjectModel;
@synthesize persistentStoreCoordinator=__persistentStoreCoordinator;
- (NSManagedObjectModel *)managedObjectModel {
if (__managedObjectModel != nil) {
return __managedObjectModel;
}
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"MyModel" withExtension:@"momd"];
__managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return __managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (__persistentStoreCoordinator != nil) {
return __persistentStoreCoordinator;
}
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"DemoApp.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;
}
- (NSManagedObjectContext *)managedObjectContext {
if (__managedObjectContext != nil) {
return __managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
__managedObjectContext = [[NSManagedObjectContext alloc] init];
[__managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return __managedObjectContext;
}
- (NSURL *)applicationDocumentsDirectory {
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
- (void)saveContext {
NSError *error = nil;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil) {
if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Fetch the launches from Core Data
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"MyData" inManagedObjectContext:context];
[request setEntity:entity];
NSArray *results = [context executeFetchRequest:request error:nil];
// Iterate through the results and log them
for (NSManagedObject *object in results) {
NSLog(@"Found %@", [object valueForKey:@"myAttribute"]);
}
// Add a new entry for this launch
NSString *launchTitle = [NSString stringWithFormat:@"launch %d", [results count]];
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
[object setValue:launchTitle forKey:@"myAttribute"];
[self saveContext];
NSLog(@"Added: %@", launchTitle);
[self.window makeKeyAndVisible];
return YES;
}
@end
```
### 1.4 示例说明
下面是一个简单的示例,展示如何使用 Core Data 存储和检索应用的启动次数:
```objc
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"MyData" inManagedObjectContext:context];
[request setEntity:entity];
NSArray *results = [context executeFetchRequest:request error:nil];
for (NSManagedObject *object in results) {
NSLog(@"Found %@", [object valueForKey:@"myAttribute"]);
}
NSString *launchTitle = [NSString stringWithFormat:@"launch %d", [results count]];
NSManagedObject *object = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
[object setValue:launchTitle forKey:@"myAttribute"];
[self saveContext];
NSLog(@"Added: %@", launchTitle);
```
首次启动应用时,输出为:
```
2011–02-25 05:13:23.783 DemoApp[2299:207] Added: launch 0
```
第二次启动时,输出为:
```
2011–02-25 05:15:48.883 DemoApp[2372:207] Found launch 0
2011–02-25 05:15:48.889 DemoApp[2372:207] Added: launch 1
```
### 1.5 数据模型属性类型
实体的属性有多种类型,如下表所示:
| Xcode Attribute Type | Objective - C Attribute Type | Objective - C Data Description |
| --- | --- | --- |
| Integer 16 | NSInteger16AttributeType | NSNumber(16 位整数) |
| Integer 32 | NSInteger32AttributeType | NSNumber(32 位整数) |
| Integer 64 | NSInteger64AttributeType | NSNumber(64 位整数) |
| Decimal | NSDecimalAttributeType | NSDecimalNumber(NSNumber 的十进制子类) |
| Double | NSDoubleAttributeType | NSNumber(双精度包装对象) |
| Float | NSFloatAttributeType | NSNumber(单精度包装对象) |
| String | NSStringAttributeType | NSString(字符串) |
| Boolean | NSBooleanAttributeType | BOOL(布尔值包装对象) |
| Date | NSDateAttributeType | NSDate(日期和时间值) |
| Binary data | NSBinaryDataAttributeType | NSData(无结构二进制数据) |
| Transformable | NSTransformableAttributeType | 任何非标准类型(转换为支持类型) |
### 1.6 数据模型类关系
以下是定义数据模型涉及的类及其关系:
```mermaid
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(NSManagedObjectModel):::process --> B(NSEntityDescription):::process
B --> C(NSPropertyDescription):::process
C --> D(NSAttributeDescription):::process
C --> E(NSRelationshipDescription):::process
C --> F(NSFetchedPropertyDescription):::process
```
- `NSManagedObjectModel` 是数据模型本身。
- `NSEntityDescription` 表示模型中的一个实体。
- `NSPropertyDescription` 是实体属性的抽象定义,有三个具体实现:`NSAttributeDescription`(实体的属性)、`NSRelationshipDescription`(从一个实体到另一个实体的引用)和 `NSFetchedPropertyDescription`(基于条件的实体实例子集的定义)。
## 2. 深入理解 Core Data 框架类
### 2.1 概述
很多开发者初次接触 Core Data 时,会觉得它的类关系复杂,阻碍而非促进数据访问。但实际上,Core Data 框架解决对象持久化问题的方式非常优雅。下面将详细介绍 Core Data 框架中的类及其相互作用。
### 2.2 准备工作
为了更好地理解这些类,我们可以创建一个简单的应用。使用 Single View Application 模板创建一个空白的 iPhone 应用,命名为 OrgChart,并按照前面介绍的方法添加 Core Data 框架。启动应用,确保它能正常启动,显示一个灰色屏幕,这表示可以继续构建基于 Core Data 的应用。
### 2.3 核心类介绍
Core Data 中常见的交互类如下图所示:
```mermaid
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(NSFetchRequest):::process --> B(NSManagedObjectContext):::process
C(NSManagedObjectModel):::process --> B
D(NSPersistentStore):::process --> B
E(NSManagedObject):::process --> B
F(Typical User Code):::process --> B
G(NSPersistentStoreCoordinator):::process --> B
```
- `NSManagedObjectContext`:托管对象上下文,包含对 `NSManagedObject` 类型的托管对象的引用。代码通过向上下文添加托管对象来存储数据,使用 `NSFetchRequest` 类实现的获取请求来检索数据。
- `NSPersistentStoreCoordinator`:持久存储协调器,用于初始化上下文。
- `NSManagedObjectModel`:数据模型,定义了要持久化的实体及其属性。
### 2.4 模型定义类
#### 2.4.1 类介绍
所有 Core Data 应用都需要一个对象模型,实体有属性、关系和获取属性三种类型的属性。以下是定义模型涉及的类及其作用:
| 类名 | 作用 |
| --- | --- |
| NSManagedObjectModel | 数据模型本身 |
| NSEntityDescription | 模型中的一个实体 |
| NSPropertyDescription | 实体属性的抽象定义 |
| NSAttributeDescription | 实体的属性 |
| NSRelationshipDescription | 从一个实体到另一个实体的引用 |
| NSFetchedPropertyDescription | 基于条件的实体实例子集的定义 |
#### 2.4.2 创建组织架构数据模型
下面我们创建一个表示公司组织架构的数据模型:
1. 在 Xcode 中,选择“File > New > New File”,从 iOS Core Data 模板中选择“Data Model”类型,创建一个名为 OrgChart 的数据模型。
2. 打开数据模型文件,添加一个新的 `Organization` 实体,并为其添加两个属性:`id` 和 `name`。`id` 属性使用 `Integer 16` 类型,`name` 属性使用 `String` 类型。
3. 同样地,创建一个名为 `Person` 的实体,也包含 `id` 和 `name` 两个属性。
4. 创建从 `Organization` 实体到 `Person` 实体的关系,命名为 `leader`。
5. 创建从 `Person` 实体到自身的关系,命名为 `employees`。默认情况下,Xcode 创建的是一对一关系,由于一个领导者可以管理多个下属,需要将 `employees` 关系改为一对多关系。具体操作如下:
- 点击 Xcode 工具栏中 View 上方最右侧的按钮,显示 Xcode 的实用工具面板。
- 点击实用工具面板顶部最右侧的按钮,显示数据模型检查器。
- 勾选“To - Many Relationship”旁边的框,将 `employees` 关系改为一对多关系。
此时的数据模型如下:
```mermaid
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(NSManagedObjectModel):::process --> B(NSEntityDescription - Organization):::process
A --> C(NSEntityDescription - Person):::process
B --> D(NSAttributeDescription - id):::process
B --> E(NSAttributeDescription - name):::process
C --> F(NSAttributeDescription - id):::process
C --> G(NSAttributeDescription - name):::process
B --> H(NSRelationshipDescription - leader):::process
H --> C
C --> I(NSRelationshipDescription - employees):::process
I --> C
```
### 2.5 总结
通过以上步骤,我们了解了如何为现有项目添加 Core Data 功能,以及 Core Data 框架中各个类的作用和相互关系。Core Data 提供了强大的数据存储和管理功能,能够帮助开发者更方便地处理数据持久化问题。在实际开发中,我们可以根据具体需求灵活运用这些知识,构建出高效、稳定的应用。
0
0
复制全文
相关推荐










