引言
在這個(gè)教程中,你會(huì)看到在Xcode提供的初始化代碼模板和數(shù)據(jù)模型編輯器資源中,用Swift語言寫出你的第一個(gè)Core Data app,將會(huì)是一件多么容易上手的事情
- 使用Xcode的模型編輯器在Core Data中創(chuàng)建你想存儲(chǔ)的模型數(shù)據(jù)
- 在Core Data中添加一條新記錄
- 從Core Data中獲取一組記錄
- 在列表視圖中顯示用戶的數(shù)據(jù)
你還可以看到一個(gè)Core Data在在后臺(tái)是如何與各組件進(jìn)行交互的。我們正在超越自我,但-是時(shí)候簡歷一個(gè)應(yīng)用程序了!
本文翻譯自 http://www.raywenderlich.com/85578/first-core-data-app-using-swift
Ray的說明:本文是Core Data by Tutorials一書中iOS8 Feast部分章節(jié)的微縮版本,讓你了解一下這是一本什么樣的書。我們希望你喜歡!
開始教程
打開Xcode,然后選擇 Single View Application 模板,創(chuàng)建一個(gè)新的iPhone工程,將其命名為 HitList,并勾選 Use Core data。
檢查看看Xcode的 Use Core data 框架 AppDelegate.swift
中自動(dòng)生成了 Core data stack 樣板代碼。
Core Data 堆棧是由一組便于保存和檢索信息的對(duì)象所組成。還有一個(gè)目的是管理Core Data狀態(tài)作為一個(gè)表示數(shù)據(jù)模型等等的整體。
Note:不是所有的Xcode模板都可以選擇 Use Core data 的選項(xiàng)。在Xcode 6中,只有 Master-Detail Application 和 Single View Application 兩個(gè)模板可以有該選項(xiàng)。
本文例子中得app非常簡單。就是會(huì)有一個(gè)命名為“hit list”的列表視圖,你能夠?qū)⒚Q添加到列表中,你將使用Core Data來保證數(shù)據(jù)存儲(chǔ)。在本教程中,我們不會(huì)以任何暴力形式強(qiáng)迫你,你可以認(rèn)為這個(gè)app是個(gè)“favorites list”,用于記錄你的好友,這當(dāng)然沒有問題!
點(diǎn)擊進(jìn)入Main.storyboard
在Interface Builder中打開。選擇View Controller 然后改變他的常規(guī)高度和寬度匹配iPhone的縱向模式:
接著,嵌入一個(gè)導(dǎo)航控制器到視圖控制器中。從Xcode的 Editor 菜單,選擇 Embed In…\ Navigation Controller 。
回到Interface Builder,從對(duì)象庫的標(biāo)示圖中拖拽一個(gè)Table View
出來,并覆蓋整個(gè)視圖。
然后再拖拽一個(gè)Bar Button Item
放置到新增加的視圖控制器的導(dǎo)航欄上。最后,雙擊Bar Button Item
將文本設(shè)置為 Add 。你的畫布應(yīng)該像下面的截圖那樣:
每次你點(diǎn)擊頂端右側(cè)的Add
時(shí),將會(huì)在屏幕上出現(xiàn)一個(gè)包含文本框的警告,你可以在里面輸入某人的名字到文本框中。退去警告將保存名字并刷新列表視圖顯示所有你保存過的名字。
在你完成這些功能之前,你需要連接視圖控制器和列表視圖的數(shù)據(jù)源。按住Ctrl拖拽列表視圖到導(dǎo)航欄上方黃色的視圖控制器圖標(biāo),如下圖所示,然后點(diǎn)擊dataSource
:
你可能會(huì)疑惑為什么不需要設(shè)置列表視圖的代理,這是因?yàn)辄c(diǎn)擊cell并不會(huì)觸發(fā)任何的事件。沒有比這更簡單的了!
通過按下 Command-Option-Enter 或者選擇Xcode工具條目上的中間按鈕,打開輔助編輯器。按住Ctrl拖拽
列表視圖到ViewController.swift
,在類定義中插入outlet:
取名為tableView,如下行所示:
@IBOutlet weak var tableView: UITableView!
按住Ctrl拖拽Add
按鈕到ViewController.swift
,同時(shí)創(chuàng)建一個(gè)action代替outlet生成一個(gè)方法名為addName
的事件:
@IBAction func addName(sender: AnyObject){
}
現(xiàn)在你可以參考下表格視圖和按鈕條目的action代碼。接著,設(shè)置標(biāo)示圖的模型,在ViewController.swift
中添加如下屬性。
//Insert below the tableView IBOutlet
var names = [String]()
names
是一個(gè)可變的數(shù)組,用來保存顯示列表視圖上的字符。
將viewDidLoad
的實(shí)現(xiàn)替換成如下代碼:
override func viewDidLoad() {
super.viewDidLoad()
title = "\"The List\""
tableView.registerClass(UITableViewCell.self,
forCellReuseIdentifier: "Cell")
}
這里將在列表視圖中注冊(cè)一個(gè)UITableViewCell
的類,你這樣做將會(huì)使你再隊(duì)列cell的時(shí)候,讓列表視圖返回一個(gè)正確類型的cell。
還是在ViewController.swift
, ViewController
將通過編輯類聲明來確認(rèn)遵守UITableViewDataSource
協(xié)議:
//Add UITableViewDataSource to class declaration
class ViewController: UIViewController, UITableViewDataSource {
此時(shí),Xcode將報(bào)錯(cuò)關(guān)于viewController沒有遵守協(xié)議。
在viewDidLoad
下面實(shí)現(xiàn)如下數(shù)據(jù)源方法來解決這個(gè)問題:
// MARK: UITableViewDataSource
func tableView(tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return names.count
}
func tableView(tableView: UITableView,
cellForRowAtIndexPath
indexPath: NSIndexPath) -> UITableViewCell {
let cell =
tableView.dequeueReusableCellWithIdentifier("Cell")
as UITableViewCell
cell.textLabel!.text = names[indexPath.row]
return cell
}
如果你使用過UITableView
,這些代碼將會(huì)看起來很熟悉。第一個(gè)方法是說明列表視圖的行數(shù)和names
數(shù)組的字符串個(gè)數(shù)一樣多。
第二個(gè)方法tableView(_:cellForRowAtIndexPath:)
,隊(duì)列他們的列表視圖cell并按照names
中字符串填充.
先不要運(yùn)行app。你還需要輸入字符串好讓列表視圖來顯示他們。
實(shí)現(xiàn)你之前拖拽的代碼addName IBAction
:
//Implement the addName IBAction
@IBAction func addName(sender: AnyObject) {
var alert = UIAlertController(title: "New name",
message: "Add a new name",
preferredStyle: .Alert)
let saveAction = UIAlertAction(title: "Save",
style: .Default) { (action: UIAlertAction!) -> Void in
let textField = alert.textFields![0] as UITextField
self.names.append(textField.text)
self.tableView.reloadData()
}
let cancelAction = UIAlertAction(title: "Cancel",
style: .Default) { (action: UIAlertAction!) -> Void in
}
alert.addTextFieldWithConfigurationHandler {
(textField: UITextField!) -> Void in
}
alert.addAction(saveAction)
alert.addAction(cancelAction)
presentViewController(alert,
animated: true,
completion: nil)
}
每當(dāng)你點(diǎn)擊Add
按鈕時(shí),該方法將會(huì)彈出一個(gè)帶有文本框和兩個(gè)按鈕Save
和Cancel
的UIAlertController
。
點(diǎn)擊Save
將會(huì)插入你當(dāng)前文本框上的內(nèi)容到names
數(shù)組中,并且會(huì)刷新列表視圖。由于names數(shù)組是支持列表視圖的模型,所以無論你輸入什么到文本框中,都會(huì)在列表視圖上展示。
最后,該第一次運(yùn)行你的程序了,點(diǎn)擊Add
按鈕,警告控制器就會(huì)像這個(gè)樣子:
添加4到5個(gè)名稱到列表中。你應(yīng)該會(huì)獲得如下樣式:
你的列表視圖會(huì)展示你保存名稱的數(shù)組中的數(shù)據(jù),但這里最大的問題是缺少持續(xù)性。這個(gè)數(shù)組只是存在內(nèi)存中,如果你強(qiáng)退或者重啟你的設(shè)備,你的名單將會(huì)消失。
Core Data提供了持續(xù)性,這意味著他能以一個(gè)更持久的狀態(tài)存儲(chǔ)數(shù)據(jù),使他能在app重啟或者設(shè)備重啟之后還存在。
你還沒有添加Core Data, 所以在你退出app后沒有什么可以保存下來。讓我們?cè)囈幌驴纯?。如果你用的是真機(jī)調(diào)試,按住Home建,或者在你的模擬器中按下 Shift+Command+H,這樣將會(huì)讓你回到熟悉的網(wǎng)格主頁。
從主頁上點(diǎn)擊HitList
圖標(biāo),重新回到app的前臺(tái)。名稱還是留在屏幕上,怎么回事?
但你點(diǎn)擊Home鍵時(shí),app從前臺(tái)進(jìn)入到后臺(tái)。這時(shí),操作系統(tǒng)會(huì)暫時(shí)凍結(jié)你內(nèi)存上的所有內(nèi)容,包括你的names數(shù)組。同樣地道理,當(dāng)你喚醒a(bǔ)pp返回到前臺(tái),操作系統(tǒng)將恢復(fù)到之前的狀態(tài),就像你沒有離開過一樣。
Apple 在iOS4之后引入了多線程, 他們?yōu)橛脩魟?chuàng)建了一個(gè)無縫的體驗(yàn),但這為開發(fā)者的持久性數(shù)據(jù)帶來了來疑惑。這些名稱真的是持久的嗎?
不,這并不是持久的。如果你在程序快速切換頁面完全殺死app或者關(guān)掉你的手機(jī),那些名稱將會(huì)消失。你當(dāng)然可以去驗(yàn)證他。在程序運(yùn)行的前臺(tái),雙擊Home鍵進(jìn)入程序快速切換頁面,如下:
從這里,向上滑出HitList的快照來終止應(yīng)用程序。這應(yīng)該不會(huì)存在一絲HitList的內(nèi)存(這里沒有雙關(guān)語)。返回到主頁點(diǎn)擊HitList的圖標(biāo)重新啟動(dòng)app,驗(yàn)證名稱是否消失。
如果你開發(fā)過iOS或者熟悉多線程編程的方法,內(nèi)存暫存和持久性的區(qū)別顯而易見。但在用戶的眼里,他們并不關(guān)心名稱是否還存在內(nèi)存中,他們不關(guān)心app是進(jìn)入后臺(tái),然后回來,或者app是否被保存,并重新加載。
他們?cè)谝獾氖钱?dāng)他們返回的時(shí)候,名稱是否還在。
所以,在本教程中你即將學(xué)會(huì)的是你一個(gè)讓你在重新啟動(dòng)app時(shí)依然保存有之前數(shù)據(jù)的持久化教程。
為你的數(shù)據(jù)創(chuàng)建模型
現(xiàn)在你知道改如何驗(yàn)證數(shù)據(jù)的持久性了,那就讓我們開始Core Data吧!HitList的目標(biāo)非常簡單:持久化你輸入的名稱,使它們?cè)谀阒匦聠?dòng)app后,依然可見。
到現(xiàn)在為止,你已經(jīng)實(shí)現(xiàn)用Swift字符串在內(nèi)存中儲(chǔ)存名稱。在這個(gè)章節(jié),你將用Core Data對(duì)象替換這些字符串。
第一步,先創(chuàng)建一個(gè)闡述在磁盤上表示Core Data的managed object model
。默認(rèn)情況下,Core Data 使用SQLite數(shù)據(jù)庫進(jìn)行持久化存儲(chǔ),所以你可以認(rèn)為數(shù)據(jù)模型就是數(shù)據(jù)庫架構(gòu)。
Note
: 你會(huì)在這個(gè)教程中遇到頗多managed
單詞。如果你再類名中見到managed
這個(gè)單詞,比如NSManagedObjectContrxt
,說明你再處理一個(gè)Core Data的類。Managed
表示Core Data對(duì)象生命周期的Core Data數(shù)據(jù)管理。
但是不要以為所有的Core Data類都包含managed
,事實(shí)上,大多數(shù)是不包含的。對(duì)于Core Data類的完整列表,請(qǐng)查看OC中得頭文件CoreData/CoreData.h
當(dāng)你在創(chuàng)建HitList工程時(shí)勾選了Core Data,Xcode會(huì)為你自動(dòng)生成一個(gè)名為HitList.xcdatamodeld
的數(shù)據(jù)模型文件。
點(diǎn)擊并打開HitList.xcdatamodeld
,你將看到如下強(qiáng)大的數(shù)據(jù)模型編輯器界面:
數(shù)據(jù)模型編輯器界面有很多功能,從現(xiàn)在開始,我們專注于創(chuàng)建單一的Core Data實(shí)體。
在左側(cè)點(diǎn)擊 Add Entity
創(chuàng)建一個(gè)新的實(shí)體,雙擊新的實(shí)體,將名稱更改為Person
,如下:
你可能會(huì)疑惑衛(wèi)生么模型編輯器要使用術(shù)語"Enity",難道你只是簡單地定義一個(gè)新的類?正如你很快要看到,Core Data有他自己的詞匯。下面是你會(huì)經(jīng)常遇到的一些術(shù)語的簡單整合:
-
entity
在Core Data中是一個(gè)類定義。典型例子是雇員
或者公司
。在關(guān)系型數(shù)據(jù)庫中,一個(gè)實(shí)體相當(dāng)于一個(gè)表。 -
attribute
是附加到特定實(shí)體上的一條信息。例如雇員
實(shí)體能包含雇員的名字,職位和年薪。在數(shù)據(jù)庫中,一個(gè)屬性相當(dāng)于一個(gè)表中得特定字段。 -
relationship
是多個(gè)實(shí)體之間的鏈接。在Core Data中,兩個(gè)實(shí)體之間的關(guān)系叫做對(duì)一關(guān)系,多個(gè)實(shí)體間的關(guān)系叫做對(duì)多關(guān)系。例如,一個(gè)經(jīng)理可以和多個(gè)雇員這個(gè)就是對(duì)多關(guān)系,但一個(gè)雇員只能有一個(gè)經(jīng)理,這就是對(duì)一關(guān)系。
Note
:你可能已經(jīng)注意到,實(shí)體看起來有點(diǎn)像類,類似的,attribute/relationship看起來有點(diǎn)像properties。他們有什么區(qū)別呢?你可以認(rèn)為Core Data的實(shí)體當(dāng)做一個(gè)定義類,把Core Data管理對(duì)象當(dāng)做這個(gè)類的實(shí)例
現(xiàn)在你已經(jīng)知道attribute是什么了,回到模型編輯器界面在Person
中添加一個(gè)attribute。選擇左手邊的Person
,點(diǎn)擊Attributes
下的加號(hào)(+)。設(shè)置一個(gè)新的屬性名,取名為name
并設(shè)置他的type為String
:
在Core Data中,屬性有很多種數(shù)據(jù)類型--其中一種是String。
保存數(shù)據(jù)到Core Data
在ViewController.swift
頂端引入頭文件:
//Add below "import UIKit"
import CoreData
如果你之前使用過OC的框架,你可能需要在你工程的Build Phases
中鏈接框架,在Swift中,一個(gè)簡單地import
就是你所有需要開始使用Core Data的API要做的事情。
接著,替換之前列表視圖的模型如下:
//Change [String] to [NSManagedObject]
var people = [NSManagedObject]()
你需要存儲(chǔ)的時(shí)Person
的實(shí)體,而不僅僅只是名字,所以你需要將列表視圖的數(shù)據(jù)模型數(shù)組重命名為people
。它現(xiàn)在擁有的時(shí)一個(gè)NSManagedObject
的實(shí)例而不僅僅只是簡單地字符串。
NSManagedObject
表示存儲(chǔ)在Core Data中的一個(gè)單一對(duì)象,你必須使用它來創(chuàng)建,編輯,保存和刪除來完成你的Core Data持久化存儲(chǔ)。正如你很快就要看到的,NSManagedObject
是一個(gè)模型接口(shap shifter)
。他以實(shí)體的形式存在在你的數(shù)據(jù)模型中,你可以隨意使用你定義的attributes和relationship。
因?yàn)槟愀淖兞肆斜硪晥D模型,你必須替換掉你之前實(shí)現(xiàn)的數(shù)據(jù)源的方法,如下:
//Replace both UITableViewDataSource methods
func tableView(tableView: UITableView,
numberOfRowsInSection section: Int) -> Int {
return people.count
}
func tableView(tableView: UITableView,
cellForRowAtIndexPath
indexPath: NSIndexPath) -> UITableViewCell {
let cell =
tableView.dequeueReusableCellWithIdentifier("Cell")
as UITableViewCell
let person = people[indexPath.row]
cell.textLabel!.text = person.valueForKey("name") as String?
return cell
}
最顯著的變化在cellForRowAtIndexPath
中,替換模型數(shù)組中與cell匹配的對(duì)應(yīng)字符串,你可以使用語cell相對(duì)應(yīng)的NSManagedObject
。
設(shè)置你從NSManagedObject
中獲取的名字屬性,如下:
cell.textLabel.text = person.valueForKey("name") as String
為什么必須這樣做?事實(shí)證明,NSManagedObject
并不知道你再數(shù)據(jù)模型重定義的name
屬性,所以沒有辦法直接用屬性訪問它。Core Data 提供讀出值的唯一辦法只有鍵-值編碼,就是通常所說的KVC。
Note
:如果你是iOS開發(fā)的新手,你可能對(duì)KVC或者鍵-值編碼不熟悉。
KVC是Cocoa和Cocoa Touch通過間接使用標(biāo)識(shí)對(duì)象屬性的字符串來訪問對(duì)象屬性的機(jī)制。在這種情況下,KVC使NSManagedObject
感覺像是字典。
鍵-值編碼可用于繼承自NSObject
的所有類,包括NSManagedObject
。你不能夠在沒有繼承自NSObject
的Swift對(duì)象中用KVC訪問屬性
接著,替換保存事件addName @IBAction
方法如下:
let saveAction = UIAlertAction(title: "Save",
style: .Default) { (action: UIAlertAction!) -> Void in
let textField = alert.textFields![0] as UITextField
self.saveName(textField.text)
self.tableView.reloadData()
}
這需要在輸入文本到文本框中,然后通過一個(gè)方法叫saveName
。添加saveName
到ViewController.swift
,如下所示:
func saveName(name: String) {
//1
let appDelegate =
UIApplication.sharedApplication().delegate as AppDelegate
let managedContext = appDelegate.managedObjectContext!
//2
let entity = NSEntityDescription.entityForName("Person",
inManagedObjectContext:
managedContext)
let person = NSManagedObject(entity: entity!,
insertIntoManagedObjectContext:managedContext)
//3
person.setValue(name, forKey: "name")
//4
var error: NSError?
if !managedContext.save(&error) {
println("Could not save \(error), \(error?.userInfo)")
}
//5
people.append(person)
}
這里是Core Data的補(bǔ)充,這段代碼的作用:
-
在你可以保存或者檢索你的Core Data存儲(chǔ)之前,你需要先獲得你的
NSManagedObjectContext
,你可以把托管對(duì)象文本認(rèn)為是在內(nèi)存中暫存的管理對(duì)象。想象一下把儲(chǔ)存一個(gè)新的管理對(duì)象到Core Data看成兩個(gè)步驟:首先,你插入一個(gè)新的管理對(duì)象到managed object context;然后,隨你樂意提交你的管理對(duì)象到managed object context來儲(chǔ)存到磁盤上。
Xcode已經(jīng)生成了一個(gè)managed object context 當(dāng)做新工程模板的一部分——記住,這里僅僅是在你一開始已經(jīng)選擇了
Use Core Data
選項(xiàng)。這樣會(huì)默認(rèn)創(chuàng)建managed object context的property在application delegate當(dāng)中。你要先得到app delegate的引用,你才訪問它。 -
你創(chuàng)建了一個(gè)新的管理對(duì)象,然后插入到managed object context中。你可以同時(shí)完成
NSManagedObject
的初始化:init(entity:insertIntoManagedObjectContext:)
。你可能想知道
NSEnityDescription
是怎么一回事,回想一下,我們把NSManagedObject
稱作模型接口(shap shifter)
類是因?yàn)樗硎疽粋€(gè)實(shí)體。一個(gè)實(shí)體描述是在運(yùn)行時(shí)從帶有NSManagedObject
實(shí)例的數(shù)據(jù)模型的實(shí)體定義的鏈接。 隨著得到
NSManagedObject
,你可以通過使用鍵-值編碼設(shè)置name
屬性。你必須拼寫KVC的key值(這里指"name"),而且它必須存在在你的數(shù)據(jù)模型中,否則你的app可能會(huì)在運(yùn)行時(shí)奔潰。提交你你修改到
person
然后通過調(diào)用managed object context中得save
來保存到磁盤上。注意,save
的參數(shù)是一個(gè)指向NSError
的指針。如果你的存儲(chǔ)操作有任何的錯(cuò)誤,你將能夠檢查出錯(cuò)誤,并在必要的時(shí)候提醒用戶。恭喜你!你新的管理對(duì)象現(xiàn)在已經(jīng)可以安全的存儲(chǔ)在Core data的持久性存儲(chǔ)中。插入新的管理對(duì)象到
people
數(shù)組中,這樣就能在你刷新時(shí),顯示在列表視圖里。
這里會(huì)比一個(gè)字符串?dāng)?shù)組稍稍復(fù)雜一些,但并不會(huì)難。這里的一些代碼-獲取managed object context 和實(shí)體-能搞在你的init
或者viewDidLoad
只生成一次,然后重復(fù)使用。這里為了簡單,在每一個(gè)方法你都實(shí)現(xiàn)了一次。
編譯并運(yùn)行app,然后添加一些名字:
如果你的名字確實(shí)被儲(chǔ)存在Core Data中,你的HitList app應(yīng)該能通過持久化測試。雙擊Home鍵回到快速app切換頁面,上滑HitList app殺死進(jìn)程。
從頁面中點(diǎn)擊app并重新啟動(dòng),稍等片刻,怎么回事?列表視圖怎么會(huì)是空的?
你已經(jīng)保存到Core Data了,但是重啟app后,people
數(shù)組卻依然還是什么都沒有!其實(shí)那些數(shù)據(jù)已經(jīng)坐在那里等你餓了,只是你還沒有取得它。
從Core Data中讀取數(shù)據(jù)
為了從你的持久化存儲(chǔ)中為managed object context讀取數(shù)據(jù),你必須把他拿出來。添加如下方法到ViewController.swift
中:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
//1
let appDelegate =
UIApplication.sharedApplication().delegate as AppDelegate
let managedContext = appDelegate.managedObjectContext!
//2
let fetchRequest = NSFetchRequest(entityName:"Person")
//3
var error: NSError?
let fetchedResults =
managedContext.executeFetchRequest(fetchRequest,
error: &error) as [NSManagedObject]?
if let results = fetchedResults {
people = results
} else {
println("Could not fetch \(error), \(error!.userInfo)")
}
}
一步一步來解釋這些代碼都做了什么:
正如上一章節(jié)提到的,在你使用Core Data之前,你需要一個(gè)managed object context,讀取數(shù)據(jù)也一樣。你需要通過application delegate來獲取一個(gè)managed object context的引用。
顧名思義,
NSFetchRequest
是負(fù)責(zé)從Core Data中讀取數(shù)據(jù)的類。獲取請(qǐng)求十分強(qiáng)大且靈活,你可以用請(qǐng)求來讀取一組滿足特定條件的對(duì)象(例如:給我讀取所有舉著在Wisconsin并且至少在公司工作三年以上的雇員),也可以單個(gè)值(例如:給我讀取數(shù)據(jù)庫中名字最長的雇員),功能不單單這些。
讀取請(qǐng)求有一些提煉返回結(jié)果的修飾詞。從現(xiàn)在開始,你應(yīng)該知道NSEntityDescription
是其中一個(gè)修飾語(這一個(gè)是必須的)。
設(shè)置過去請(qǐng)求的實(shí)體property,或者以init(entityName:)
進(jìn)行初始化,讀取特定實(shí)體的對(duì)象。這就是你再獲取所有Person
實(shí)體要做的事。處理讀取請(qǐng)求給managed object context去做一些繁重的任務(wù)。
executeFetchRequest(_:error:)
返回一個(gè)在請(qǐng)求中指定標(biāo)準(zhǔn)的管理對(duì)象可選數(shù)組。
Note
:如果沒有匹配的讀取請(qǐng)求條件的對(duì)象,該方法返回一個(gè)包含空數(shù)組的可選值。
如果在讀取時(shí)發(fā)生了錯(cuò)誤,則方法返回一個(gè)包含0的可選值。如果發(fā)生這種情況,你可以檢查NSError
并采取相應(yīng)措施。
再次編譯并運(yùn)行代碼,現(xiàn)在,你應(yīng)該可以看到你之前添加的名字列表。
非常棒!他們起死回生了!再添加一些名字到列表里,然后重新啟動(dòng)app來驗(yàn)證保存和讀取是否正確運(yùn)行。只要不是刪除app,重置你的模擬器或把你的手機(jī)進(jìn)行出廠恢復(fù),無論如何你的米那個(gè)字列表都會(huì)出現(xiàn)在列表視圖當(dāng)中。
接下來該何去何從?
在這個(gè)教程中,你已經(jīng)體驗(yàn)到了基本的Core Data概念:數(shù)據(jù)模型,實(shí)體,attributes,管理對(duì)象,managed object context和讀取請(qǐng)求。這里是完整的Hitlist工程。