刚刚发现了一个coredata的讲解,分了三部,但是还是看不太懂

本文将引导您完成CoreData的基础学习,包括建立数据模型、验证其健壮性、将其可视化于表格视图中,以及导入或预载已有数据,优化应用性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在iPhone所有数据存储的方法里面,Core Data是重要数据存储的最佳选择。它能降低你应用的内存开销,提升响应速度,并把你从繁琐的代码中解脱出来。

然而,学习Core Data之路异常久远。不过这也是这一系列教程的由来 – 让你快速掌握Core Data基础知识。

作为该系列教程的第一部分,我们将为我们的对象建立一个可视化数据模型。为保证其有效性,我们会做一个快速肮脏测试(dirty test验证其健壮性和有效性),然后将其勾在一个表视图(table view)里,这样我们可以看到这一列对象。

系列教程的第二部分,我们将讨论如何将数据预先载入到Core Data中,这样我们的应用启动时就初始化好了。

最后的部分,我们将讨论如何使用NSFetchedResultsController来优化应用,达到降低内存开销以及改进响应时间的目的。

在本教程开始之前,我建议先翻阅我以前写的SQLite for iPhone Developers教程,这会让你更容易理解。另外,2个教程做的应用(app)都是一样的,只是这次我们用的是Core Data!

创建一个Core Data工程

下面让我们开始!建立一个新的Window-based Application,勾选“Use Core Data for storage”,将工程命名为“FailedBanksCD.”

在开始前,我们快速看一下建好的工程。首先展开Resources并双击FailedBanksCD.xcdatamodel,会弹出一个可视化编辑器-这就是我们接下来会用到的模型对象图示。现在我们先把它关闭。

然后看看FailedBanksCDAppDelegate.m。在这里你会看见已经为我们实现的一些新函数,用于建立Core Data”堆”。新增了一个 managed object context,一个managed object model, persistent store coordinator. 啊??

别担心。名字虽然开始听起来奇怪,一旦你打通“任督二脉”就很容易理解到他们是什么。

  • Managed Object Model:你可以把它当作是数据库规划图。这是一个包含其他对象(也叫Entities)定义的类,对象存储在数据库里面。通常会用刚刚瞄过的可视化编辑器来设定数据库的对象,它们的特性(attributes),它们是如何相互关联的。然而,你也可以用代码来实现。
  • Persistent Store Coordinator:你可以把它当作是数据库的连接。在这里你设定用来存储对象的数据库的真实名称和位置,以及需要时用来保存的管理对象上下文(managed object context)。
  • Managed Object Context:你可以把它当作是一个数据库取出对象的“暂存器”。对我们来说它也是这三个里面最重要的,因为我们大多都在上面工作。基本上,无论何时需要获取对象,插入对象或是删除对象,你都要调用管理对象上下文(managed object context)的方法(或者说大部分时间!)。

 

这是系列教程的第二部分,有助于你加快掌握基本的Core Data内容。

系列教程一中,我们为对象建立了可视化数据模型,运行了快速肮脏测试并勾在一个表视图(table view)中来显示。而在这个教程,我们将讨论如何把已有的数据导入或者预先载入到Core Data里面,这样我们的应用开始时会有一些好的默认数据。

在系列教程的最后部分,我们将讨论如何使用NSFetchedResultsController来优化应用,降低内存开销和提升响应时间。

Preloading / Importing Existing Data

预载/导入已有数据

我们要如何在Core Data中预先载入数据呢?流行的解决方案有两种:

  • 启动时从外部源填入Core Data。对此,注意到数据库还没有导入,应用可以启动时从外部来源(例如SQLite数据库或是XML文件)读取数据。
  • 在SQLite数据库中预先填充。对此我们可以Core Data在模型基础上建立数据库结构,然后使用工具来填入数据库。这类工具可以是基于Core Data API的Mac或者iPhone应用,或是一些直接填入SQLite数据库的程序。一旦数据库填好了,只需将其包含到应用里面作为默认数据库,在不存在已有的数据库情况下。

我们将会采用第二种方式,因为它更简单更有效。为了填充数据库,我们只需稍微扩展一下已有的Python脚本。

注意到为什么用Python脚本而不是用基于Core Data API的工具来来导入数据,是因为我们现在有点走底层的样子,将来可能会容易损坏…但是对于本教程我认为第一,由于我们刚刚接触了SQLite,这样对学习的经验巩固更好,而且对事情的进展看的更加清楚;第二,更简单!

所以,让我们拿出工程中产生的sqlite数据库的拷贝。找出相关文件的最简单的方法就是在程序委托(application delegate)中persistentStoreCoordinator函数里面storeUrl一行下方设置一个断点。你可以通过检测storeUrl变量的内容来获取sqlite数据库备份文件的完整路径。找到它并拷到你的Python脚本目录。

一旦你找到数据库,使用sqlite3来简单看看数据库的模样:

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

sqlite3 FailedBanksCD.sqlite

 

sqlite3> .schema

CREATE TABLE ZFAILEDBANKDETAILS ( Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER,

    Z_OPT INTEGER, ZZIP INTEGER, ZINFO INTEGER, ZUPDATEDDATE TIMESTAMP,

    ZCLOSEDATE TIMESTAMP );

CREATE TABLE ZFAILEDBANKINFO ( Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER,

    Z_OPT INTEGER, ZDETAILS INTEGER, ZNAME VARCHAR, ZSTATE VARCHAR,

    ZCITY VARCHAR );

CREATE TABLE Z_METADATA (Z_VERSION INTEGER PRIMARY KEY,

    Z_UUID VARCHAR(255), Z_PLIST BLOB);

CREATE TABLE Z_PRIMARYKEY (Z_ENT INTEGER PRIMARY KEY, Z_NAME VARCHAR,

    Z_SUPER INTEGER, Z_MAX INTEGER);

CREATE INDEX ZFAILEDBANKDETAILS_ZINFO_INDEX ON ZFAILEDBANKDETAILS (ZINFO);

CREATE INDEX ZFAILEDBANKINFO_ZDETAILS_INDEX ON ZFAILEDBANKINFO (ZDETAILS);

 

sqlite> select from ZFAILEDBANKINFO;

1|2|1|1|Test Bank|Testland|Testville

2|2|1|2|Test Bank|Testland|Testville

3|2|1|3|Test Bank|Testland|Testville

 

sqlite> select from ZFAILEDBANKDETAILS;

1|1|1|12345|1|292794835.855615|292794835.679693

2|1|1|12345|2|292794875.943392|292794875.768675

3|1|1|12345|3|292795809.375025|292795809.215297

 

sqlite> select from Z_PRIMARYKEY;

1|FailedBankDetails|0|3

2|FailedBankInfo|0|3

这里有段快速描述。Z_METADATA包含了一些关于Core Data需要实现的模型信息。Z_PRIMARYKEY包含了(在其他东西里面)各个实体所用到的最大key。

至于ZFAILEDBANKINFO跟ZFAILEDBANKDETAILS,这些是我们的主要数据表。Z_PK是各个表的唯一id,Z_ENT是他们的实体id(跟Z_PRIMARYKEY表中列出的一样),最后那些是我们的普通字段。

 

 

迄今为止,我们现在的处境跟当初用SQLite3的时候一样。然而,我们不需要写如此多的代码(注意一下FailedBankDatabase类中那段缺失的原始SQL语句代码),添加诸如插入/删除之类的操作也很简便。

有一项显著的便利性是用Core Data才能体现出来的:使用NSFetchedResultsController。

比较理想的状态是在用户目前所见的table view中加载部分行。幸运的是,苹果为我们造就了这一便利,提供了一个很棒的工具类:NSFetchedResultsController。

因此,开始打开FailedBanksListViewController.h,移除旧有的NSArray failedBankInfos,替换为一个新的NSFetchedResultsController:

@interface FailedBanksListViewController : UITableViewController <NSFetchedResultsControllerDelegate> { NSFetchedResultsController *_fetchedResultsController; NSManagedObjectContext *_context;}@property (nonatomic, retain) NSFetchedResultsController *fetchedResultsController;@property (nonatomic, retain) NSManagedObjectContext *context;@end

在synthesize段移除老的failedBankInfos代码并添加:

@synthesize fetchedResultsController = _fetchedResultsController;

以防忘记,在dealloc方法中fetchedResultsController设为nil

self.fetchedResultsController = nil;

另一个绝妙的地方就是你可以在viewDidUnload里面将NSFetchedResultsController设为nil,这就意味着在低内存情况下,内存的所有数据都可以释放掉(在视图离开视线的情况下)。你只需要在viewDidUnload里面把它清空(并保证在viewDidLaod中重新初始化)

- (void)viewDidUnload { self.fetchedResultsController = nil;}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值