iOS: Core Data入门
Core Data是ORM框架,很像.NET框架中的EntityFramework。使用的基本步骤是:
- 在项目属性里引入CoreData.framework (标准库)
- 在项目中新建DataModel (生成*.xcdatamodeld文件)
- 在DataModel里创建Entity
- 为Entity生成头文件(菜单Editor/Create NSMangedObject Subclass...)
- 在项目唯一的委托类(AppDelegate.h, AppDelegate.m)里添加managedObjectContext 用来操作Core Data
- 代码任意位置引用 managedObjectContext 读写数据
模型:(注意:myChapter, myContent这些关系都是Cascade,这样删父对象时才会删除子对象)
生成的头文件:
/* Book.h */ @interface Book : NSManagedObject @property (nonatomic, retain) NSNumber * bookId; @property (nonatomic, retain) NSString * name; @property (nonatomic, retain) NSString * author; @property (nonatomic, retain) NSString * summary; @property (nonatomic, retain) NSSet *myChapters; @end @interface Book (CoreDataGeneratedAccessors) - (void)addMyChaptersObject:(NSManagedObject *)value; - (void)removeMyChaptersObject:(NSManagedObject *)value; - (void)addMyChapters:(NSSet *)values; - (void)removeMyChapters:(NSSet *)values; @end /* Chapter.h */ @class Book; @interface Chapter : NSManagedObject @property (nonatomic, retain) NSNumber * chapId; @property (nonatomic, retain) NSString * name; @property (nonatomic, retain) NSNumber * orderId; @property (nonatomic, retain) Book *ownerBook; @property (nonatomic, retain) NSManagedObject *myContent; @end /* TextContent.h */ @class Chapter; @interface TextContent : NSManagedObject @property (nonatomic, retain) NSNumber * chapId; @property (nonatomic, retain) NSString * text; @property (nonatomic, retain) Chapter *ownerChapter; @end
委托类代码
AppDelegate.h
// AppDelegate.h #import <UIKit/UIKit.h> #import <CoreData/CoreData.h> #import "Book.h" #import "Chapter.h" #import "TextContent.h" @interface AppDelegate : UIResponder <UIApplicationDelegate> @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) NSManagedObjectContext *managedObjectContext; @end
AppDelegate.m
@implementation AppDelegate @synthesize managedObjectContext = _managedObjectContext; -(NSManagedObjectContext *)managedObjectContext { if (_managedObjectContext != nil) { return _managedObjectContext; } _managedObjectContext = [[NSManagedObjectContext alloc]init]; // 设置数据库路径 NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]lastObject]; NSURL *storeDataBaseURL = [url URLByAppendingPathComponent:@"BOOKS.sqlite"]; // 创建presistentStoreCoordinator NSError *error = nil; NSPersistentStoreCoordinator *presistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[NSManagedObjectModel mergedModelFromBundles: nil]]; // 指定存储类型和路径 if (![presistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeDataBaseURL options:nil error:&error]) { NSLog(@"error : %@", error); } [_managedObjectContext setPersistentStoreCoordinator: presistentStoreCoordinator]; return _managedObjectContext; }
使用_managedObjectContext操作Core Data
// 保存新对象 -(void) testStore { // 从AppDelegate 获得context AppDelegate *appDelegate = [UIApplication sharedApplication].delegate; NSManagedObjectContext *context = [appDelegate managedObjectContext]; // 第一个章节 TextContent *content1 = [NSEntityDescription insertNewObjectForEntityForName:@"TextContent" inManagedObjectContext:context]; content1.chapId = [NSNumber numberWithInt:100]; content1.text = @"hello1"; Chapter *chapter1 = (Chapter *)[NSEntityDescription insertNewObjectForEntityForName:@"Chapter" inManagedObjectContext:context]; chapter1.name = @"hello1"; chapter1.orderId = [NSNumber numberWithInt:0]; chapter1.chapId = [NSNumber numberWithInt:100]; chapter1.myContent = content1; // 第二个章节 TextContent *content2 = [NSEntityDescription insertNewObjectForEntityForName:@"TextContent" inManagedObjectContext:context]; content2.chapId = [NSNumber numberWithInt:100]; content2.text = @"hello2"; Chapter *chapter2 = (Chapter *)[NSEntityDescription insertNewObjectForEntityForName:@"Chapter" inManagedObjectContext:context]; chapter2.name = @"hello2"; chapter2.orderId = [NSNumber numberWithInt:1]; chapter2.chapId = [NSNumber numberWithInt:101]; chapter2.myContent = content2; // 书籍对象 Book *book = (Book *)[NSEntityDescription insertNewObjectForEntityForName:@"Book" inManagedObjectContext:context]; book.bookId = [NSNumber numberWithInt:100]; book.name = @"hello"; book.author = @"Kitty"; book.summary = @"test"; [book addMyChaptersObject:chapter1]; [book addMyChaptersObject:chapter2]; // 提交到持久存储 if ([context hasChanges]) { [context save:nil]; } } // 读取对象 -(void) testRead { // 从AppDelegate 获得context AppDelegate *appDelegate = [UIApplication sharedApplication].delegate; NSManagedObjectContext *context = [appDelegate managedObjectContext]; // 生成查询对象 (查询全部数据) NSEntityDescription *entityDescr = [NSEntityDescription entityForName:@"Book" inManagedObjectContext:context]; NSFetchRequest *request = [[NSFetchRequest alloc]init]; [request setEntity:entityDescr]; // 执行查询 NSError *error; NSArray *arrayBooks = [context executeFetchRequest:request error:&error]; // 定义排序方式 (根据集合中Chapter对象的orderId属性排序,升序) NSSortDescriptor *chaptersDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"orderId" ascending:YES]; // 遍历结果集 for (Book *book in arrayBooks) { // 使用当前对象属性 NSLog(@"book name = %@", book.name); // 使用当前对象的集合属性,转成数组 NSArray *arrayChapters = [book.myChapters allObjects]; // 排序 arrayChapters = [arrayChapters sortedArrayUsingDescriptors:[NSArray arrayWithObjects:chaptersDescriptor,nil]]; // 遍历子数组 for (Chapter *chapter in arrayChapters) { NSLog(@"chapter name = %@", chapter.name); TextContent *content = (TextContent*) chapter.myContent; NSLog(@"chapter text = %@", content.text); } } } // 更新对象属性 -(void) testUpdate { // 从AppDelegate 获得context AppDelegate *appDelegate = [UIApplication sharedApplication].delegate; NSManagedObjectContext *context = [appDelegate managedObjectContext]; // 生成Request对象 NSEntityDescription *entityDescr = [NSEntityDescription entityForName:@"Book" inManagedObjectContext:context]; NSFetchRequest *request = [[NSFetchRequest alloc]init]; [request setEntity:entityDescr]; // 执行查询 NSError *error; NSArray *array = [context executeFetchRequest:request error:&error]; // 更改对象属性 Book * book = array[0]; book.name = @"BOOKS"; // 提交到持久存储 if ([context hasChanges]) { [context save:nil]; } } // 删除对象 -(void) testRemove { // 从AppDelegate 获得context AppDelegate *appDelegate = [UIApplication sharedApplication].delegate; NSManagedObjectContext *context = [appDelegate managedObjectContext]; // 生成Request对象 NSEntityDescription *entityDescr = [NSEntityDescription entityForName:@"Book" inManagedObjectContext:context]; NSFetchRequest *request = [[NSFetchRequest alloc]init]; [request setEntity:entityDescr]; // 执行查询 NSError *error; NSArray *array = [context executeFetchRequest:request error:&error]; // 遍历删除对象,因为在模型里把关系设置为Cascade,所以子对象会被自动删除 for (Book *book in array) { [context deleteObject:book]; } // 提交到持久存储 if ([context hasChanges]) { [context save:nil]; } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述
2013-10-10 auto_ptr解析
2013-10-10 智能指针,大爱啊
2012-10-10 改进的日志类
2012-10-10 python : logging模块format类
2012-10-10 python: 不同级别的日志输出到不同文件的日志类