技术宅,fat-man

增加语言的了解程度可以避免写出愚蠢的代码

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

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];
    }
}
复制代码

 

posted on   codestyle  阅读(229)  评论(0编辑  收藏  举报

编辑推荐:
· 如何编写易于单元测试的代码
· 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: 不同级别的日志输出到不同文件的日志类
点击右上角即可分享
微信分享提示