CoreData(二)

  • 參考書籍:CORE DATA by Tutorials
  • 默認(rèn)有swift基礎(chǔ)哆料。
  • 默認(rèn)已閱讀上一篇內(nèi)容召噩。

親愛的們儡湾,上一篇我們簡單的講了Core Data的存儲以及讀取咐容,我們已經(jīng)說過了Core Data是對象圖形化管理模式,既然對象放在最前面庄撮,那么在Core Data中最正確的操作方式應(yīng)該是使用對象和屬性來進(jìn)行操作背捌。
這一篇的主要內(nèi)容:

  • 使用所有的Attributes的類型。
  • 使用對象來進(jìn)行儲存以及讀取數(shù)據(jù)洞斯。
  • data model的檢驗限制功能毡庆。

(1)烙如、使用所有的Attributes的類型
在這一篇中我們也用一個Demo來演示么抗,Demo如圖所示:

已拖拽好控件

那塊綠色表示最喜歡的顏色。
那只斯派克表示頭像厅翔。
(一切從簡,以CoreData操作為核心搀突。)
在name和age的輸入框輸入數(shù)據(jù)并且選擇好日期后刀闷,點擊Add按鈕會將name、年齡、最喜歡的顏色甸昏、生日顽分、頭像全部保存起來。
點擊show按鈕會跳轉(zhuǎn)到下一界面施蜜,如圖:
自行創(chuàng)建一個新的文件并于此界面聯(lián)系起來卒蘸,這里不演示如何操作,若有疑問請留言

在這個頁面中會顯示之前保存的數(shù)據(jù)翻默。

在上一篇中我們知道在進(jìn)行Core Data操作之前我們得先建立data model(數(shù)據(jù)模板)缸沃,對此有問題的同學(xué)請參考[http://www.reibang.com/p/96e2b321449c]
這是我們建立的數(shù)據(jù)模型:

注意Entity名字以大寫開頭,Attributes名字以小寫開頭

Note:你應(yīng)該發(fā)現(xiàn)了在.xcdatamodeld中Attributes(屬性)的Type(類型)中有三種整形:Integer 16, Integer 32 和 Integer 64修械。* 區(qū)別就在于占據(jù)多大內(nèi)存趾牧,每種類型儲存數(shù)的大小都有一個范圍(當(dāng)然范圍越大的占據(jù)內(nèi)存越多):
Range for 16-bit integer: -32768 to 32767
Range for 32-bit integer: –2147483648 to 2147483647
Range for 64-bit integer: –9223372036854775808 to 9223372036854775807
在實際使用中應(yīng)該根據(jù)需求來確定類型,比如說肯污,在這里年齡使用Integer 16就完全夠用腰根。

在Type有一個類型是“Binary Data”蔑歌,這是一個萬能的類型,可以儲存一切你能想到的可以翻譯成二進(jìn)制的東西,包括圖片靠闭、PDF、‘小電影’等等揭北。
但是時間花銷和空間花銷仿佛是一個悖論寨辩,這里也是一樣,這種方便的操作方式权逗,犧牲了很大的系統(tǒng)花銷美尸。也就是說即使你只是想獲取他的名字,但是他也會把整個Binary(二進(jìn)制)加載到緩存中斟薇,而這會十分影響用戶體驗师坎。
十分幸運,Core Data早就想到這個問題了堪滨。選擇我們的Binary Data類型的屬性在右邊的屬性欄中你會發(fā)現(xiàn)一個名為Allows External Storage的選擇框胯陋,像這樣:


當(dāng)你勾選了Allows External Storage以后,CoreData將給給每一個值都獨立儲存袱箱,并會生成一個URI作為入口 遏乔。

Note:Allows External Storage只有binary data類型擁有,并且发笔,當(dāng)你勾選了這個選擇框以后你就不能使用屬性來詢問Core Data盟萨。
(據(jù)說勾選了這個選擇框以后還容易導(dǎo)致數(shù)據(jù)丟失,未驗證了讨。)

  • 存儲非標(biāo)準(zhǔn)類型數(shù)據(jù)
    有一些數(shù)據(jù)類型在Type一欄中并沒有出現(xiàn)捻激,比如UIColor等制轰。
    你會如何儲存UIColor?像這樣(e.g., red: 255, green: 101, blue: 155)胞谭?但是垃杖,事實上,你可以將UIColor轉(zhuǎn)化為data丈屹,然后使用Binary Data類型來進(jìn)行儲存调俘。當(dāng)你需要讀取的時候再將data類型轉(zhuǎn)化為UIColor類型。
    Transformable Type
    Transformable類型可以儲存任何繼承自NSCoding的對象旺垒,任何你自定義的對象若是繼承自NSCoding也可以用Transformable類型來儲存彩库。

(2)、使用對象來進(jìn)行儲存以及讀取數(shù)據(jù)
上一篇中我們用key-value來存儲袖牙、讀取數(shù)據(jù)侧巨,look like this:

//Set the name
Test.setValue(name1, forKey: "name")
//Get the name
let name = Test.valueForKey("name")

你的確可以這樣操作。但是鞭达,這并不意味著你應(yīng)該這樣操作司忱。
key-value并沒有充分利用swift類型判斷和xcode 自動完成的功能。

最好的方法應(yīng)該是給每一個Entity創(chuàng)建一個子類畴蹭,每一個Entity的屬性都有自己的類型坦仍。
xcode可以自動給Core Data modal中的Entity生成一個類。像這樣操作:

選中.xcdatamodeled文件叨襟,然后點擊Editor->Create NSManagedObject Subclass-> 選中數(shù)據(jù)模板->選中要生成類的Entity繁扎,然后一直點next

在使用我們新創(chuàng)建的對象管理類來進(jìn)行存醋以及讀取等操作之前,我們還有最后一步要做糊闽。選擇. xcdatamodeled選中Test Entity梳玫,打開右邊的屬性欄,將我們剛才創(chuàng)建的類和Entity連接起來右犹,這看起來似乎和controller和類連接起來有些類似提澎,不過有些不同的就是,這次我們得在類的名字之前添加上ProjectName.念链。那么在這里就是CoreDataTest2.Test*:

最新的xcode也許會在這一欄自動填寫盼忌,但經(jīng)檢驗出錯,所以還是自己重新填一下

通過對象管理類來進(jìn)行存儲讀取有以下兩個好處:

    1. 充分利用了xcode和編譯器掂墓。
  • 2.你可以重定義已經(jīng)存在的方法谦纱。
    有些方法不被允許繼承

上一篇我們已經(jīng)了解過,在進(jìn)行Core Data操作時第一步就是獲取managedContext(‘暫存器’)君编。上一篇我們通過 application.delegate來獲取‘暫存器’跨嘉,但是這樣操作看起來更像是一個全局變量。這一篇我用類與類之間的屬性傳遞的方法吃嘿,來獲取這個‘暫存器’對象祠乃,打開AppDelegate.swift
插入以下代碼:
<pre><code>
func application(application:UIApplication,didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let viewController = self.window!.rootViewController as ViewController
viewController.managedContext = self.managedObjectContext
return true
}</code></pre>

打開ViewController.swift,添加頭文件“import CoreData”窘游,添加一個全局變量。

    //這個變量就是我們的‘暫存器’跳纳,而這個暫存器在AppDelegate.swift中已經(jīng)初始化。
    var managedContext:NSManagedObjectContext!

給addButton方法添加代碼
<pre><code> func insertSampleData() {
//1
let name = self.name.text
let age = self.age.text.toInt()!
let favoriteColor=self.favoriteColor.backgroundColor!
let birthday = self.birthday.date
let avatar = self.Avatar.image!
//2
let entity = NSEntityDescription.entityForName("Test", inManagedObjectContext: managedContext)
let TestObject = Test(entity: entity!, insertIntoManagedObjectContext: managedContext)
//3
TestObject.name=name
TestObject.age=age
TestObject.favoriteColor=favoriteColor
TestObject.birthday=birthday
let avatarData=UIImagePNGRepresentation(avatar)
TestObject.avatar=avatarData
//4
var error: NSError?
if !managedContext.save(&error) {
println("Could not save (error), (error!.userInfo)")
}

</code></pre>

解釋一下這一段代碼:

  • //1 獲取在屏幕中輸入的各種信息贪嫂。
  • //2 新建一個Test對象TestObject寺庄,使用初始化方法
    init(entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext?)
  • //3 給新建的TestObject的變量賦值。
  • //4 保存‘暫存器’力崇。
    是不是使用對象來進(jìn)行保存方便許多斗塘,是的!

現(xiàn)在運行一下app亮靴,填寫信息(age一欄請?zhí)顚懻麛?shù)馍盟,否則出錯,這里只考慮CoreData相關(guān)操作)茧吊,點擊add按鈕以后信息被儲存贞岭,點擊show按鈕以后跳轉(zhuǎn)到下一界面,但是并沒有進(jìn)行任何操作搓侄,現(xiàn)在給showViewController添加代碼瞄桨。

讀取數(shù)據(jù)
打開ShowViewController.swift,在viewDidLoad()中添加以下代碼讶踪。
<pre><code>
override func viewDidLoad() {
super.viewDidLoad()
//1
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext!
//2
let request = NSFetchRequest(entityName:"Test")
var error: NSError? = nil
var results = managedContext.executeFetchRequest(request, error: &error) as! [Test]!
//3
let TestObject=results[results.count-1]
let name = TestObject.name
let age = TestObject.age
let birthday = TestObject.birthday
let favoriteColor:UIColor = TestObject.favoriteColor as! UIColor
let avatar = UIImage(data: TestObject.avatar)
//4
self.Avatar=UIImageView(image: avatar)
self.name.text = name
self.age.text = "(age)"
//格式化輸出生日
var fmt=NSDateFormatter()
fmt.dateFormat = "yyyy-MM-dd"
let birthdayString = fmt.stringFromDate(birthday)
self.birthday.text = birthdayString
self.favoriteColor.backgroundColor = favoriteColor

}

</code></pre>

代碼解釋:

  • //1 獲取‘暫存器’芯侥。
  • //2 創(chuàng)建請求,發(fā)出請求并將結(jié)果轉(zhuǎn)化為Test數(shù)組乳讥。
  • //3 取出數(shù)組中最后一個Test柱查,也就是我們在界面上只能顯示最后一個輸入信息,通過對象的屬性我們找到了之前輸入的信息云石。
  • //4 將取到的信息顯示在界面上唉工,其中favoriteColor從Anyobject轉(zhuǎn)化為UIColor,Avatar從NSData轉(zhuǎn)化為UIImage留晚。

好的酵紫,這個Demo基本就完成了,我們來運行一下吧:

別忘了點擊Add按鈕
成功顯示错维,Demo的確夠簡陋~~~

到了這一篇的最后部分了奖地。
數(shù)據(jù)驗證:

有時候我們對數(shù)據(jù)的內(nèi)容有所限制,比如說年齡不能是負(fù)的赋焕,在coredata中這種驗證并不用我們自己來寫代碼参歹,我們的data model就有這樣的功能。

打開我們的data model隆判,選中我們要驗證的屬性犬庇,點開右邊的屬性輔助欄僧界,如下圖所示:

年齡不能小于0,記得打上邊上的√

在紅色框中我們可以限定最大值 和 最小值臭挽。

Note:當(dāng)我們修改我們的data model以后在運行程序會發(fā)生錯誤捂襟,原因就是我們修改了我們的model,最簡單的解決方法就是把我們的模擬器reset一下欢峰。


對data model的任何修改都可能使之發(fā)生錯誤葬荷,這個時候不妨把這個按鈕按一下

好的,接下來我們監(jiān)測下當(dāng)輸入超出我們的限定之后發(fā)生了什么纽帖,還記得我們的保存時的error嗎宠漩,我們將輸入的年齡為-1,我們來看一下輸出懊直。

error.userInfo輸出了剛才輸入的全部信息扒吁,包括錯誤信息

既然發(fā)生了error,個么問題來了室囊,如何處理error雕崩?
<pre><code>
var error: NSError?
if !managedContext.save(&error) {
println("Could not save (error), (error!.userInfo)")
if error!.code == NSValidationNumberTooLargeError{
println("值過大")
}
if error!.code == NSValidationNumberTooLargeError {
println("值過小")
}
}
</code></pre>

  if error!.code == NSValidationNumberTooLargeError
  if error!.code == NSValidationNumberTooLargeError

這兩句判斷語句能準(zhǔn)確的告訴我們到底是發(fā)生了什么錯誤,根據(jù)不同錯誤以及實際情況來進(jìn)行處理融撞,靈活機(jī)動晨逝。


這一篇內(nèi)容大體就是這樣了,主要講了通過對象來進(jìn)行存儲以及讀取懦铺,而這樣操作的好處就是更加方便捉貌,充分利用了swift以及xcode的特性,也不容易出錯冬念。
源代碼已上傳Github:https://github.com/superxlx/CoreDataTest2

好了趁窃,在下一篇再見。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末急前,一起剝皮案震驚了整個濱河市醒陆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌裆针,老刑警劉巖刨摩,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異世吨,居然都是意外死亡澡刹,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門耘婚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來罢浇,“玉大人,你說我怎么就攤上這事∪卤眨” “怎么了攒岛?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長胞锰。 經(jīng)常有香客問我灾锯,道長,這世上最難降的妖魔是什么嗅榕? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任挠进,我火速辦了婚禮,結(jié)果婚禮上誊册,老公的妹妹穿的比我還像新娘。我一直安慰自己暖璧,他們只是感情好案怯,可當(dāng)我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著澎办,像睡著了一般嘲碱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上局蚀,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天麦锯,我揣著相機(jī)與錄音,去河邊找鬼琅绅。 笑死扶欣,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的千扶。 我是一名探鬼主播料祠,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼澎羞!你這毒婦竟也來了髓绽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤妆绞,失蹤者是張志新(化名)和其女友劉穎顺呕,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體括饶,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡株茶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了图焰。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片忌卤。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖楞泼,靈堂內(nèi)的尸體忽然破棺而出驰徊,到底是詐尸還是另有隱情笤闯,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布棍厂,位于F島的核電站颗味,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏牺弹。R本人自食惡果不足惜浦马,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望张漂。 院中可真熱鬧晶默,春花似錦、人聲如沸航攒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽漠畜。三九已至币他,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間憔狞,已是汗流浹背蝴悉。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留瘾敢,地道東北人拍冠。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像簇抵,于是被迫代替她去往敵國和親倦微。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容

  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 10,954評論 6 13
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法正压,類相關(guān)的語法欣福,內(nèi)部類的語法,繼承相關(guān)的語法焦履,異常的語法拓劝,線程的語...
    子非魚_t_閱讀 31,622評論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)嘉裤,斷路器郑临,智...
    卡卡羅2017閱讀 134,651評論 18 139
  • 1.Core Data classes NSManagedObjectModel:用來創(chuàng)建數(shù)據(jù)模型,存儲屬性和保存...
    xiaocheche閱讀 343評論 0 1
  • 這個世界總是有和你生活格格不入的“賤人們”躺翻,時間久了就只能說丧叽,不好意思,我對你零容忍公你。從開始進(jìn)入我可愛的可敬的二流...
    x流氓先生閱讀 594評論 1 1