一.文章概要
这篇文章其实是在第七篇<<7- coreData基本扩展保存NSArray>>基础上来研究下 coreData 如何直接保存 NSDictionary 类型.
其实很多地方都和上一篇文章中提到的很像,下边只提几个关键的地方.
二.关键点
2.1 属性类型设置
这里在模型文件中增加取名为'penDict'的属性名,用来保存 NSDictionary,设置类型为'Transformable'. 如下图:

Smaller icon
2.2 保存的实例对象
这里主要说下保存 Entity 实例对象.
首先,和保存 NSArray 中一个样,被保存的 Entity 是我们自己单独创建的,并不是NSManagedObject Subclass的子类
. 如下图:

Smaller icon
代码如下:
BookInfo.h:
#import <Foundation/Foundation.h>
#import "Student.h"
@interface BookInfo : NSObject
@property (nonatomic, assign) NSNumber *bookID;
@property (copy, nonatomic) NSString *bookName;
@property (strong,nonatomic) Student *student;
@end
BookInfo.m: (被保存的类中我们要写 NSCoding 的代码)
#import "BookInfo.h"
@implementation BookInfo
- (void) encodeWithCoder: (NSCoder *)coder
{
[coder encodeObject:self.bookID forKey:@"bookID"];
[coder encodeObject:self.bookName forKey:@"bookName"];
[coder encodeObject:self.student forKey:@"student"];
}
- (id)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
self.bookID = [aDecoder decodeObjectForKey:@"bookID"];
self.bookName = [aDecoder decodeObjectForKey:@"bookName"];
}
return self;
}
@end
2.3 上下文保存 NSDictionary
写入方法代码: //插入数据 - (IBAction)insertData{ NSLog(@"插入数据");
//====== 3'
//第一组数据
Student *student = [NSEntityDescription insertNewObjectForEntityForName:@"Student" inManagedObjectContext:self.managedContext];
student.name = @"张三2";
student.id = @(11);
BookInfo *book = [[BookInfo alloc] init];
book.bookID = @(121);
book.bookName = @"<老人与海2>";
BookInfo *book1 = [[BookInfo alloc] init];
book1.bookID = @(121);
book1.bookName = @"<老人与海2>";
student.penDict = @{@"book":book,@"book1":book1};
//第二组数据
Student *student2 = [NSEntityDescription insertNewObjectForEntityForName:@"Student" inManagedObjectContext:self.managedContext];
student2.name = @"李四2";
student2.id = @(23);
BookInfo *book2 = [[BookInfo alloc] init];
book2.bookID = @(242);
book2.bookName = @"<飞鸟集2222>";
BookInfo *book22 = [[BookInfo alloc] init];
book22.bookID = @(242);
book22.bookName = @"<飞鸟集22222>";
student2.penDict = @{@"book2":book2,@"book22":book22};
//保存,用 save 方法
NSError *error = nil;
BOOL success = [self.managedContext save:&error];
if (!success) {
[NSException raise:@"访问数据库错误" format:@"%@",[error localizedDescription]];
}
}
2.4 读取保存的 NSDictionary
读取代码如下:
//读取数据库文件
- (IBAction)readData{
NSLog(@"读取数据");
dispatch_async(dispatch_get_main_queue(), ^{
// 初始化一个查询请求
NSFetchRequest *request = [[NSFetchRequest alloc] init];
// 设置要查询的实体
request.entity = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:self.managedContext];
//以上代码简写成下边
// NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Student"];
// 设置排序(按照age降序)
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"id" ascending:NO];
request.sortDescriptors = [NSArray arrayWithObject:sort];
// 设置条件过滤(搜索name中包含字 串"Itcast-1"的记录,注意:设置条件过滤时,数据库SQL语句中的%要用*来代替,所以%Itcast-1%应该写成*Itcast-1*)
// NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %@", @"*Itcast-1*"];
// request.predicate = predicate;
// 执行请求
NSError *error = nil;
NSArray *objs = [self.managedContext executeFetchRequest:request error:&error];
if (error) {
[NSException raise:@"查询错误" format:@"%@", [error localizedDescription]];
}
NSLog(@"-----------------------------------");
// 遍历数据
int index = 0;
for (Student *stu in objs) {
NSLog(@"student:%d---name=%@", index++,stu.name);
NSDictionary *dict = stu.penDict;
NSLog(@"dict : %@",dict);
Book *book2 = dict[@"book2"];
Book *book22 = dict[@"book22"];
NSLog(@"-book2'name:%@----book22'name%@",book2.bookName,book22.bookName);
}
});
}
三.结尾
到这里,保存 NSDictionary 的基本逻辑就完成了,具体的 Demo 代码可以在我的 GitHub 上找到 Demo地址
这是自己网上搜索和自己摸索出来的保存 NSDictionary的方法,总觉自己单独又创建一个 Entity类不是很好,希望有更好的方法的朋友,一定告诉我下,不胜感激!!!
交流
欢迎大家关注我的微博和我GitHub,我会不时分享和转发一些大牛的技术贴和开源项目.
GitHub:https://github.com/lilongcnc
博客地址:http://www.lilongcnc.cc