Suche senden
Hochladen
16 CoreData
•
0 gefällt mir
•
583 views
Tom Fan
Folgen
iOS Core Data:关系对象模型
Weniger lesen
Mehr lesen
Technologie
Melden
Teilen
Melden
Teilen
1 von 50
Jetzt herunterladen
Downloaden Sie, um offline zu lesen
Empfohlen
02 Objective-C
02 Objective-C
Tom Fan
14 Saving Loading and Application States
14 Saving Loading and Application States
Tom Fan
05 MapKit and Text Input
05 MapKit and Text Input
Tom Fan
17 Localization
17 Localization
Tom Fan
03 Managing Memory with ARC
03 Managing Memory with ARC
Tom Fan
07 View Controllers
07 View Controllers
Tom Fan
Network and Multitasking
Network and Multitasking
yarshure Kong
CH04:認識物件
CH04:認識物件
Justin Lin
Empfohlen
02 Objective-C
02 Objective-C
Tom Fan
14 Saving Loading and Application States
14 Saving Loading and Application States
Tom Fan
05 MapKit and Text Input
05 MapKit and Text Input
Tom Fan
17 Localization
17 Localization
Tom Fan
03 Managing Memory with ARC
03 Managing Memory with ARC
Tom Fan
07 View Controllers
07 View Controllers
Tom Fan
Network and Multitasking
Network and Multitasking
yarshure Kong
CH04:認識物件
CH04:認識物件
Justin Lin
Ch07 使用 JSTL
Ch07 使用 JSTL
Justin Lin
CH09:Collection與Map
CH09:Collection與Map
Justin Lin
10. 資料永續與交換
10. 資料永續與交換
Justin Lin
Template mb-kao
Template mb-kao
xwcoder
Backbone js and requirejs
Backbone js and requirejs
Chi-wen Sun
合久必分,分久必合
合久必分,分久必合
Qiangning Hong
Servlet & JSP 教學手冊第二版 - 課後練習解答
Servlet & JSP 教學手冊第二版 - 課後練習解答
Justin Lin
Introduction and Internals of SQL on hadoop by WangHaihua
Introduction and Internals of SQL on hadoop by WangHaihua
Wang Haihua
Node way
Node way
Ethan Zhang
NoSQL-MongoDB介紹
NoSQL-MongoDB介紹
國昭 張
Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器
Justin Lin
Script with engine
Script with engine
Webrebuild
Static server介绍
Static server介绍
sun jamie
CH16:整合資料庫
CH16:整合資料庫
Justin Lin
Docker進階探討
Docker進階探討
國昭 張
Parse, cloud code 介紹
Parse, cloud code 介紹
wantingj
Servlet & JSP 教學手冊第二版 - 第 1 章:簡介Web應用程式
Servlet & JSP 教學手冊第二版 - 第 1 章:簡介Web應用程式
Justin Lin
Hibernate查询
Hibernate查询
llying
Ch03 請求與回應
Ch03 請求與回應
Justin Lin
Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應
Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應
Justin Lin
iOS程序设计-数据持久化
iOS程序设计-数据持久化
qiyutan
15 Subclassing UITableViewCell
15 Subclassing UITableViewCell
Tom Fan
Weitere ähnliche Inhalte
Was ist angesagt?
Ch07 使用 JSTL
Ch07 使用 JSTL
Justin Lin
CH09:Collection與Map
CH09:Collection與Map
Justin Lin
10. 資料永續與交換
10. 資料永續與交換
Justin Lin
Template mb-kao
Template mb-kao
xwcoder
Backbone js and requirejs
Backbone js and requirejs
Chi-wen Sun
合久必分,分久必合
合久必分,分久必合
Qiangning Hong
Servlet & JSP 教學手冊第二版 - 課後練習解答
Servlet & JSP 教學手冊第二版 - 課後練習解答
Justin Lin
Introduction and Internals of SQL on hadoop by WangHaihua
Introduction and Internals of SQL on hadoop by WangHaihua
Wang Haihua
Node way
Node way
Ethan Zhang
NoSQL-MongoDB介紹
NoSQL-MongoDB介紹
國昭 張
Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器
Justin Lin
Script with engine
Script with engine
Webrebuild
Static server介绍
Static server介绍
sun jamie
CH16:整合資料庫
CH16:整合資料庫
Justin Lin
Docker進階探討
Docker進階探討
國昭 張
Parse, cloud code 介紹
Parse, cloud code 介紹
wantingj
Servlet & JSP 教學手冊第二版 - 第 1 章:簡介Web應用程式
Servlet & JSP 教學手冊第二版 - 第 1 章:簡介Web應用程式
Justin Lin
Hibernate查询
Hibernate查询
llying
Ch03 請求與回應
Ch03 請求與回應
Justin Lin
Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應
Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應
Justin Lin
Was ist angesagt?
(20)
Ch07 使用 JSTL
Ch07 使用 JSTL
CH09:Collection與Map
CH09:Collection與Map
10. 資料永續與交換
10. 資料永續與交換
Template mb-kao
Template mb-kao
Backbone js and requirejs
Backbone js and requirejs
合久必分,分久必合
合久必分,分久必合
Servlet & JSP 教學手冊第二版 - 課後練習解答
Servlet & JSP 教學手冊第二版 - 課後練習解答
Introduction and Internals of SQL on hadoop by WangHaihua
Introduction and Internals of SQL on hadoop by WangHaihua
Node way
Node way
NoSQL-MongoDB介紹
NoSQL-MongoDB介紹
Ch05 Servlet 進階 API、過濾器與傾聽器
Ch05 Servlet 進階 API、過濾器與傾聽器
Script with engine
Script with engine
Static server介绍
Static server介绍
CH16:整合資料庫
CH16:整合資料庫
Docker進階探討
Docker進階探討
Parse, cloud code 介紹
Parse, cloud code 介紹
Servlet & JSP 教學手冊第二版 - 第 1 章:簡介Web應用程式
Servlet & JSP 教學手冊第二版 - 第 1 章:簡介Web應用程式
Hibernate查询
Hibernate查询
Ch03 請求與回應
Ch03 請求與回應
Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應
Servlet & JSP 教學手冊第二版 - 第 3 章:請求與回應
Ähnlich wie 16 CoreData
iOS程序设计-数据持久化
iOS程序设计-数据持久化
qiyutan
15 Subclassing UITableViewCell
15 Subclassing UITableViewCell
Tom Fan
09 UITableView and UITableViewController
09 UITableView and UITableViewController
Tom Fan
Html 5 native drag
Html 5 native drag
Weizhong Yang
Migrations 與 Schema操作
Migrations 與 Schema操作
Shengyou Fan
10 Editing UITableView
10 Editing UITableView
Tom Fan
Javascript
Javascript
Ryan Chung
Chapter 4 models
Chapter 4 models
Ekman Hsieh
Java华为面试题
Java华为面试题
yiditushe
Spring4.x + hibernate4.x_配置详解
Spring4.x + hibernate4.x_配置详解
zany_hui
Django development
Django development
loveyudu
Servlet & JSP 教學手冊第二版 - 第 7 章:使用 JSTL
Servlet & JSP 教學手冊第二版 - 第 7 章:使用 JSTL
Justin Lin
iPhone,ios,Object-c基础入门
iPhone,ios,Object-c基础入门
Lucien Li
iPhone,ios,Object-C基础入门
iPhone,ios,Object-C基础入门
Lucien Li
ios分享
ios分享
Lucien Li
I os 02
I os 02
信嘉 陳
Android resource-management
Android resource-management
Lucas Xu
從模組到類別
從模組到類別
Justin Lin
Nosql及其主要产品简介
Nosql及其主要产品简介
振林 谭
掌星 移动互联网开发笔记-Vol001
掌星 移动互联网开发笔记-Vol001
rainx1982
Ähnlich wie 16 CoreData
(20)
iOS程序设计-数据持久化
iOS程序设计-数据持久化
15 Subclassing UITableViewCell
15 Subclassing UITableViewCell
09 UITableView and UITableViewController
09 UITableView and UITableViewController
Html 5 native drag
Html 5 native drag
Migrations 與 Schema操作
Migrations 與 Schema操作
10 Editing UITableView
10 Editing UITableView
Javascript
Javascript
Chapter 4 models
Chapter 4 models
Java华为面试题
Java华为面试题
Spring4.x + hibernate4.x_配置详解
Spring4.x + hibernate4.x_配置详解
Django development
Django development
Servlet & JSP 教學手冊第二版 - 第 7 章:使用 JSTL
Servlet & JSP 教學手冊第二版 - 第 7 章:使用 JSTL
iPhone,ios,Object-c基础入门
iPhone,ios,Object-c基础入门
iPhone,ios,Object-C基础入门
iPhone,ios,Object-C基础入门
ios分享
ios分享
I os 02
I os 02
Android resource-management
Android resource-management
從模組到類別
從模組到類別
Nosql及其主要产品简介
Nosql及其主要产品简介
掌星 移动互联网开发笔记-Vol001
掌星 移动互联网开发笔记-Vol001
Mehr von Tom Fan
PhoneGap 通信原理和插件系统
PhoneGap 通信原理和插件系统
Tom Fan
HTML5 Web workers
HTML5 Web workers
Tom Fan
Web sockets
Web sockets
Tom Fan
Storage
Storage
Tom Fan
Semantics
Semantics
Tom Fan
Multimedia
Multimedia
Tom Fan
Intro to-html5
Intro to-html5
Tom Fan
Html5 history
Html5 history
Tom Fan
Geolocation
Geolocation
Tom Fan
File api
File api
Tom Fan
Deviceaccess
Deviceaccess
Tom Fan
Css3
Css3
Tom Fan
Webstorage
Webstorage
Tom Fan
Html5 最重要的部分
Html5 最重要的部分
Tom Fan
AT&T 的 HTML5 策略和应用现状
AT&T 的 HTML5 策略和应用现状
Tom Fan
PhoneGap 2.0 开发
PhoneGap 2.0 开发
Tom Fan
Android 平台 HTML5 应用开发
Android 平台 HTML5 应用开发
Tom Fan
HTML5 生态系统和应用架构模型
HTML5 生态系统和应用架构模型
Tom Fan
18 NSUserDefaults
18 NSUserDefaults
Tom Fan
13 UIPopoverController and Modal View Controller
13 UIPopoverController and Modal View Controller
Tom Fan
Mehr von Tom Fan
(20)
PhoneGap 通信原理和插件系统
PhoneGap 通信原理和插件系统
HTML5 Web workers
HTML5 Web workers
Web sockets
Web sockets
Storage
Storage
Semantics
Semantics
Multimedia
Multimedia
Intro to-html5
Intro to-html5
Html5 history
Html5 history
Geolocation
Geolocation
File api
File api
Deviceaccess
Deviceaccess
Css3
Css3
Webstorage
Webstorage
Html5 最重要的部分
Html5 最重要的部分
AT&T 的 HTML5 策略和应用现状
AT&T 的 HTML5 策略和应用现状
PhoneGap 2.0 开发
PhoneGap 2.0 开发
Android 平台 HTML5 应用开发
Android 平台 HTML5 应用开发
HTML5 生态系统和应用架构模型
HTML5 生态系统和应用架构模型
18 NSUserDefaults
18 NSUserDefaults
13 UIPopoverController and Modal View Controller
13 UIPopoverController and Modal View Controller
16 CoreData
1.
Core Data 范圣刚,princetoad@gmail.com, www.tfan.org
2.
• 保存和加载数据 •
Local or remote? • Archiving or Core Data? • Archiving: 对整个⽂文件进⾏行操作 • Core Data: 操作存储对象的⼦子集 • 性能
3.
对象-关系映射(ORM) • Core Data
是提供了 object-relational mapping 的⼀一 个框架,可以把 Objective-C 对象转成存储在 SQLite 数据库⽂文件的数据,反之亦然。 • Core Data 提供了⼀一种可以提取和存储数据到关系 数据库⽽而不需要了解 SQL 的能⼒力。 • 我们这⼀一个章节在 Homepwner 的 BNRItemStore 中⽤用 Core Data 替换掉原来的 keyed archiving。
4.
对 Homepwner 使⽤用Core
Data
5.
• 我们现在的 Homepwner
应⽤用使⽤用 archiving 来保 存和加载数据,对于数据量较⼩小的情况还可以, 但是对于数据量⾮非常⼤大的情况下,我们可能就想 要能够增量提取和更新数据的 Core Data。
6.
• ⾸首先,我们还是要把 Core
Data framework 加⼊入我 们的项⺫⽬目。 • 选择 Homepwner target,在 Build Phases 下⾯面, 打开 Link Binary with Libraries, 加 + 号 添加 Core Data framework
7.
模型⽂文件
8.
Core Data ⾓角⾊色
9.
• table/class ->
entity • columns/instance -> attributes • BNRItem entity
10.
• 打开 Homepwner.xcodeproj •
File -> New -> File, iOS -> Core Data, Data Model, 命 名为 Homepwner • 将会创建⼀一个 Homepwner.xcdatamodeld 的⽂文件
11.
• 从 project
navigator 中打开这个⽂文件,我们就可以 看到可以操作 Core Data model file 的⽤用户界⾯面
12.
• 找到屏幕左下⾓角的 “Add
Entity”按钮点击,⼀一个新 的 Entity 将会出现在左⼿手边的 entities 列表中,命名 为 BNRItem
13.
在 Attributes 中对应的设置属性
Attribute type itemName String serialNumber String valueInDollars Integer 32 dateCreated Date imageKey String thumbnail Binary Data thumbnail Undefined
14.
• 从 Attributes
中选择 thumbnail,点击 inspector 中 的 attribute inspector,勾选 Transient • 设成 Transient 是告诉 Core Data 我们的 thumbnail 将在运⾏行时创建,⽽而不是从⽂文件保存和加载。
15.
再增加⼀一个⽤用于排序的属性 • orderingValue ->
Double
16.
relationship • ⺫⽬目前模型⽂文件对于保存和加载 items
已经⾜足够了 • 我们再增加⼀一个新的名为 BNRAssetType 的实体, ⽤用于描述 items 的分类。 • 这样就构造出⼀一个实体间的 relation,演⽰示 Core Data 实体间关系的功能。
17.
• 再添加⼀一个名为 BNRAssetType
的实体⽂文件 • 增加⼀一个叫做 label 的属性,类型是 String,把它 作为 items 分类的名字
18.
• 现在我们需要来建⽴立 BNRAssetType
和 BNRItem 之 间的关系
19.
Homepwner 中的实体
20.
• 给模型⽂文件增加 relationships。 •
选择 BNRAssetType 实体,点击 Relationship 部分 的 + 号。 • 在 Relationship 列把这个 relation 命名为 items; • 然后从 Destination 列中选择 BNRItem; • 在 data model inspector 中,勾选 To-Many Relationship
21.
• 给 BNRItem
实体增加⼀一个名为 assetType 的关系, 把 BNRAssetType 作为⺫⽬目的,在 Inverse 列,选择 items。
22.
NSManagedObject 及其⼦子类
23.
• 当⼀一个对象被提取出来时,默认类型是 NSManagedObject,是 NSObject的⼀一个⼦子类,知 道如何跟
Core Data 互相操作。 • NSManagedObject 类似字典:持有实体中所有属 性的⼀一个 key-value pair。 • NSManagedObject 差不多就是⼀一个容器。如果我 们想让模型对象做更多⼯工作,我们必须⼦子类化 NSManagedObject。
24.
• 选中 BNRItem
实体,显⽰示 data model inspector, 并更改 Class 字段为 BNRItem。 • 现在当 BNRItem 实体被提取出来时,这个对象的 类型将会是 BNRItem。
25.
• 在 Finder
中,⾸首先备份好我们的 BNRItem.h 和 BNRItem.m ⽂文件 • 然后在 Xcode 中把这两个⽂文件从 project navigator 中删除。
26.
• 重新打开 Homepwner.xcdatamodeld •
选择 BNRItem 实体 • 然后选择从 New 菜单中选择 File,iOS -> Core Data, 选择 NSManagedObject subclass 选项,提⽰示 保存的时候,勾选“Use scalar properties for primitive data types”
27.
• Xcode 将会⽣生成两个新的
BNRItem.h 和 BNRItem.m ⽂文件 • 打开 BNRItem.h, 把 thumbnail 属性的类型改成 UIImage • 然后增加⼀一个跟之前⼀一样的⼀一个⽅方法声明 @interface BNRItem : NSManagedObject @property (nonatomic) int32_t itemName; @property (nonatomic, retain) NSString * serialNumber; @property (nonatomic) int32_t valueInDollars; @property (nonatomic) NSTimeInterval dateCreated; @property (nonatomic, retain) NSString * imageKey; @property (nonatomic, retain) NSData * thumbnailData; //@property UNKNOWN_TYPE UNKNOWN_TYPE thumbnail; @property (nonatomic, strong)UIImage *thumbnail; @property (nonatomic) double orderingValue; @property (nonatomic, retain) NSManagedObject *assetType; - (void)setThumbnailDataFromImage:(UIImage *)image; @end
28.
• NSDate 变成了
NSTimeInterval • 打开我们的 DetailViewController.h, 定位到 viewWillAppear:, 替换下⾯面的代码 // [dateLabel setText:[dateFormatter stringFromDate:[item dateCreated]]]; // 把 time interval 转换成 NSDate NSDate *date = [NSDate dateWithTimeIntervalSinceReferenceDate:[item dateCreated]]; [dateLabel setText:[dateFormatter stringFromDate:date]];
29.
• 然后,从旧的 BNRItem.m
中拷⻉贝 setThumbNailFromImage: ⽅方法到新的⽂文件 - (void)setThumbnailDataFromImage:(UIImage *)image { CGSize origImageSize = [image size]; // thumnail 的矩形⼤大⼩小 CGRect newRect = CGRectMake(0, 0, 40, 40); // 计算缩放⽐比 float ratio = MAX(newRect.size.width / origImageSize.width, newRect.size.height / origImageSize.height); // ⽣生成⼀一个带缩放因⼦子的透明位图上下⽂文 UIGraphicsBeginImageContextWithOptions(newRect.size, NO, 0.0); // ⽣生成⼀一个圆⾓角矩形路径 UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:newRect cornerRadius:5.0]; // 后续绘制 clip 到这个圆⾓角矩形 [path addClip]; // 图⽚片放到缩略图中间 CGRect projectRect; projectRect.size.width = ratio * origImageSize.width; projectRect.size.height = ratio * origImageSize.height; projectRect.origin.x = (newRect.size.width - projectRect.size.width) / 2.0; projectRect.origin.y = (newRect.size.height - projectRect.size.height) / 2.0; // 把图⽚片绘制上来 [image drawInRect:projectRect]; // 从图⽚片上下⽂文获得图⽚片,作为我们的缩略图保存 UIImage *smallImage = UIGraphicsGetImageFromCurrentImageContext(); [self setThumbnail:smallImage]; // 得到该图⽚片 PNG 形式,把它作为我们可以 archive 的数据 NSData *data = UIImagePNGRepresentation(smallImage); [self setThumbnailData:data]; // 完成以后,清除图⽚片上下⽂文资源 UIGraphicsEndImageContext(); }
30.
• 在 BNRItem.m
中重写 awakeFromFetch ⽅方法,来 从 thumbnailData 设置 thumbnail • 使⽤用 archiving 的时候我们是在 initWithCoder: 时 做的 - (void)awakeFromFetch { [super awakeFromFetch]; UIImage *tn = [UIImage imageWithData:[self thumbnailData]]; [self setPrimitiveValue:tn forKey:@"thumbnail"]; }
31.
• 我们创建⼀一个新的 BNRItem
实例时,它将会被加 ⼊入数据库。 • 当对象被添加到数据库时,它将被发送 awakeInsert 消息 • 在 BNRItem.m 中实现 awakeFromInsert • 原先我们是在 BNRItem 的 designated initializer 中 添加⼀一些附加⾏行为的 - (void)awakeFromInsert { [super awakeFromInsert]; NSTimeInterval t = [[NSDate date] timeIntervalSinceReferenceDate]; [self setDateCreated:t]; }
32.
更新 BNRItemStore
33.
BNRItemStore 和 NSManagedObjectContext
34.
• 在 BNRItemStore.h
中,导⼊入 Core Data 然后增加三 个实例变量 #import <Foundation/Foundation.h> // 导⼊入 Core Data 头⽂文件 #import <CoreData/CoreData.h> @class BNRItem; @interface BNRItemStore : NSObject { NSMutableArray *allItems; NSMutableArray *allAssetTypes; NSManagedObjectContext *context; NSManagedObjectModel *model; }
35.
• 在BNRItemStore.m 中,更改
itemArchivePath 的实 现来返回⼀一个不同的路径供 Core Data 存储数据 - (NSString *)itemArchivePath { NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentDirectory = [documentDirectories objectAtIndex:0]; // return [documentDirectory stringByAppendingPathComponent:@"items.archive"]; return [documentDirectory stringByAppendingPathComponent:@"store.data"]; }
36.
• BNRItemStore 被初始化时,它需要设置
NSManagedObjectContext 和 NSPersistentStoreCoordinator • 我们需要创建⼀一个 NSManagedObjectModel 来持 有 Homepwner.xcdatamodeld 的实体信息,并且 使⽤用这个对象初始化 persistent store coordinator • 因此我们将创建 NSManagedObjectContext 的实 例,并且指定它使⽤用这个 persistent store coordinator 来保存和加载对象
37.
• 在 BNRItemStore.m
中更新 init - (id)init { self = [super init]; if (self) { //// allItems = [[NSMutableArray alloc] init]; // NSString *path = [self itemArchivePath]; // allItems = [NSKeyedUnarchiver unarchiveObjectWithFile:path]; // // 如果数组之前没有被保存,创建⼀一个新的空数组 // if (!allItems) { // allItems = [[NSMutableArray alloc] init]; // } // 读取 Homepwner.xcdatamodeld model = [NSManagedObjectModel mergedModelFromBundles:nil]; NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model]; // SQLite ⽂文件在哪⼉儿? NSString *path = [self itemArchivePath]; NSURL *storeURL = [NSURL fileURLWithPath:path]; NSError *error = nil; if (![psc addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) { [NSException raise:@"Open failed" format:@"Reason: %@", [error localizedDescription]]; } // ⽣生成 managed object context context = [[NSManagedObjectContext alloc] init]; [context setPersistentStoreCoordinator:psc]; // 不需要管理 undo [context setUndoManager:nil]; } return self; }
38.
• 之前我们使⽤用 keyed
archiving 的时候,当我们要 求保存数据,BNRItemStore 将会写⼊入整个 NSMutableArray 的 BNRItems。 • 现在我们让它给 NSManagedObjectContext 发送 save: 消息。Context 将会更新 store.data 中从最后 ⼀一次保存其有任何变更的所有记录。 • 在 BNRItemStore.m 中,更改 saveChanges @implementation BNRItemStore - (BOOL)saveChanges { // // 返回成功或失败 // NSString *path = [self itemArchivePath]; // return [NSKeyedArchiver archiveRootObject:allItems toFile:path]; NSError *err = nil; BOOL successful = [context save:&err]; if (!successful) { NSLog(@"Error saving: %@", [err localizedDescription]); } return successful; }
39.
NSFetchRequest 和 NSPredicate
40.
• 要从 NSManagedObjectContext
提取数据,我们需 要 prepare and execute ⼀一个 NSFetchRequest。 • 当这个 fetch 请求被执⾏行以后,我们将得到⼀一个符 合这个请求的 parameters 的所有对象的⼀一个数组 • fetch 请求需要我们想要从中获取对象的⼀一个实体 的描述。这⾥里我们指定 BNRItem 实体。
41.
• 也可以设置请求的 sort
descriptors 来指定数组中 对象的顺序。 • ⼀一个 sort descriptor 具有⼀一个映射到⼀一个 attribute 的 key,和⼀一个表⽰示正序还是倒序的 BOOL 值 • 我们希望使⽤用使⽤用 orderingValue 正序排列返回的 BNRItem • 在 BNRItemStore.h 中,声明⼀一个新的⽅方法 - (void)loadAllItems;
42.
• 在 BNRItemStore.m
中定义 loadAllItems 来 prepare and execute ⼀一个 fetch 请求,并且保存结果到 allItems 数组 - (void)loadAllItems { if (!allItems) { NSFetchRequest *request = [[NSFetchRequest alloc] init]; NSEntityDescription *e = [[model entitiesByName] objectForKey:@"BNRItem"]; [request setEntity:e]; NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey:@"orderingValue" ascending:YES]; [request setSortDescriptors:[NSArray arrayWithObject:sd]]; NSError *error; NSArray *result = [context executeFetchRequest:request error:&error]; if (!result) { [NSException raise:@"Fetch failed" format:@"Reason: %@", [error localizedDescription]]; } allItems = [[NSMutableArray alloc] initWithArray:result]; } }
43.
• 在 BNRItemStore.m
中,在 init 的末尾发送这个消 息给 BNRItemStore // 不需要管理 undo [context setUndoManager:nil]; [self loadAllItems]; } return self; }
44.
• 要想有选择性的 fetch
⼀一些实例,我们可以添加⼀一 个 predicate(⼀一个 NSPredicate)到我们的 fetch 请 求,只有满⾜足这个 predicate 的对象会被返回。 • predicate 包含的是⼀一个可以为 true 或 false 的条 件。例如: // ⼀一个 predicate 的例⼦子,设定 fetch 条件 NSPredicate *p = [NSPredicate predicateWithFormat:@"valueInDollars > 50"]; [request setPredicate:p]; • predicate 也可以被⽤用来过滤⼀一个数组的内容,例如 // predicate ⽤用来过滤数组的例⼦子 NSArray *expensiveStuff = [allItems filteredArrayUsingPredicate:p];
45.
增加和删除 items
46.
• 要创建⼀一个新的 BNRItem,我们将请求
NSManagedObjectContex 从 BNRItem 实体插⼊入⼀一 个新的对象。它将返回⼀一个 BNRItem 的实例。 • 在 BNRItemStore.m 中,编辑 createItem ⽅方法 - (BNRItem *)createItem { //// BNRItem *p = [BNRItem randomItem]; // BNRItem *p = [[BNRItem alloc] init]; double order; if ([allItems count] == 0) { order = 1.0; } else { order = [[allItems lastObject] orderingValue] + 1.0; } NSLog(@"在 %d 个 items 之后添加,顺序是:%.2f", [allItems count], order); BNRItem *p = [NSEntityDescription insertNewObjectForEntityForName:@"BNRItem" inManagedObjectContext:context]; [p setOrderingValue:order]; [allItems addObject:p]; return p; }
47.
• 当⼀一个⽤用户删除了⼀一个 item
的时候,我们必须通 知 context,这样它也会被从数据库删除。 • 在 BNRItem.m 中,增加下列的代码到 removeItem: - (void)removeItem:(BNRItem *)p { // BNRItem 被从 store 中移除的时候,它的 image 也应该被从⽂文件系统删除 NSString *key = [p imageKey]; [[BNRImageStore sharedStore] deleteImageForkey:key]; // 增加通知 context 有数据被删除的代码 [context deleteObject:p]; [allItems removeObjectIdenticalTo:p]; }
48.
重排 items
49.
• 我们需要为 BNRItem
替换的最后⼀一点功能是在 BNRItemStore 中重新排序 BNRItems。 • 因为 Core Data 不会⾃自动化的处理排序,每次它在 table view 中被移动时我们必须更新 BNRItem 的 orderingValue。 • 在 BNRItemStore.m 中,修改 moveItemAtIndex:toIndex: 来处理重新排序 items
50.
- (void)moveItemAtIndex:(int)from toIndex:(int)to {
if (from == to) { return; } // 得到被移动的对象的指针,以便我们可以把它重新插⼊入 BNRItem *p = [allItems objectAtIndex:from]; // 从数组中删除 [allItems removeObjectAtIndex:from]; // 在新的位置重新插⼊入 [allItems insertObject:p atIndex:to]; // Core Data 的排序 // 为被移动的对象计算⼀一个新的 orderValue double lowerBound = 0.0; // 数组中在它之前是否有⼀一个对象? if (to > 0) { lowerBound = [[allItems objectAtIndex:to -1] orderingValue]; } else { lowerBound = [[allItems objectAtIndex:1] orderingValue] - 2.0; } double upperBound = 0.0; // 数组中在它之后是否有⼀一个对象 if (to < [allItems count] - 1) { upperBound = [[allItems objectAtIndex:to + 1] orderingValue]; } else { upperBound = [[allItems objectAtIndex:to -1] orderingValue] + 2.0; } double newOrderValue = (lowerBound + upperBound) / 2.0; NSLog(@"moving to order: %f", newOrderValue); }
Jetzt herunterladen