Swift使用CoreData時(shí)遇到的一些填坑記錄
前言
最近在做一個(gè) App 練手,其中用到了 CoreData 來(lái)存儲(chǔ)用戶的播放列表,由于 CoreData 這部分的文章還是比較少的,所以遇到了不少坑,所以寫篇隨筆記錄一下。
題外話:可以給大家看看這個(gè) App 的界面,我覺(jué)得還是挺清新的😄

P.S. 作為背景的氛圍圖片用的是 CoreImage 生成的
切入正題。
#0 何時(shí)執(zhí)行保存
起初我認(rèn)為不用顯式執(zhí)行 Xcode 給我們?cè)?AppDelegate 中生成的 saveContext 函數(shù),因?yàn)槟J(rèn)情況下 applicationWillTerminate 會(huì)執(zhí)行 saveContext,但是我發(fā)現(xiàn)這個(gè)生命周期函數(shù)壓根不靠譜,當(dāng)用戶直接從多任務(wù)視圖將 App 結(jié)束掉時(shí)這個(gè)函數(shù)根本來(lái)不及執(zhí)行完畢,導(dǎo)致我們的數(shù)據(jù)不能及時(shí)寫入本地?cái)?shù)據(jù)庫(kù)中。所以合理的調(diào)用時(shí)機(jī)我認(rèn)為還是應(yīng)該在完成一批操作以后就直接執(zhí)行一次 saveContext
下面簡(jiǎn)單貼一下我的部分代碼吧:


#1 Relationships 到底什么鬼
另外一個(gè)讓我很頭疼的就是 Relationships,寫這塊的那天可能有點(diǎn)情緒原因,看蘋果官方的 Guideline 看不進(jìn)去,而且 Google 關(guān)于 Relationships 相關(guān)的文章也十分少,索性自己悶頭研究了。
先說(shuō)說(shuō)我遇到了什么問(wèn)題,我想將屬于一個(gè)歌單的所有 Song 實(shí)體添加到 Playlist 實(shí)體的 songs 這個(gè) Relationships 中去,但是發(fā)現(xiàn)怎么加都加不進(jìn)去。我已開始的做法是先用 valueForKey 拿到 songs 屬性所代表的 NSManagedObject,然后強(qiáng)制轉(zhuǎn)換到 NSMutableSet 然后執(zhí)行添加操作,發(fā)現(xiàn)人家壓根不鳥我這個(gè)操作,雖然沒(méi)有拋異常,也沒(méi)有任何 log 打出,但是 “It does NOT work!!!”。
經(jīng)過(guò)一番研究,我發(fā)現(xiàn)了 NSManagedObject 有個(gè) mutableSetValueForKey,才發(fā)現(xiàn)當(dāng)初我真是傻了逼了....
于是用 mutableSetValueForKey 拿到這個(gè) NSMutableSet 順利執(zhí)行添加操作并保存,成功了。
#2 Type Conversion From Objective-C to Swift
這塊主要是談?wù)勔恍╆P(guān)于類型的一些事。我們知道 Swift 引入了一系列新的數(shù)據(jù)類型,比如 String、Int、Dictionary、Array,還有一個(gè)神奇的 AnyObject 和 Optional<T> 值。
這里我就直接說(shuō)了
Swift 中的 String 可以直接作為 NSString 使用,它們之間可以 Toll-Free 轉(zhuǎn)換
Int、Float、Double 仍然不是一個(gè)標(biāo)準(zhǔn)的 NSObject 對(duì)象,所以 KVC 就沒(méi)有它們什么事,所以我們?nèi)匀恍枰?NSNumber 包裝一下送入 NSManagedObject,同時(shí)拿出來(lái)的時(shí)候用 xxxValue 取出。
還有,Relationships 一定是 NSSet 類型,不是 NSArray 類型,數(shù)據(jù)庫(kù)的關(guān)系都是無(wú)序的,如果需要有序可以添加一個(gè)字段然后查詢時(shí)用 SortDescription 來(lái)排序。
最后,"!"是邪惡符號(hào),慎用。
CoreData在Swift 3.0中的一點(diǎn)改變
在Swift 2.0中我們需要從core data中query結(jié)果的時(shí)候使用的是如下方式:
func findAnimals() {
let request = NSFetchRequest(entityName:”Animal")
do {
guard let searchResults = try context.executeFetchRequest(request) as? [Animal] else {
print("Results were not of the expected structure")
}
... use(searchResults) ...
} catch {
print("Error ocurred during execution: \(error)")
}
}
注意:以上代碼試圖將executeFetchRequest返回的結(jié)果轉(zhuǎn)換為實(shí)際數(shù)據(jù)類型的數(shù)組。同時(shí)我們看到,在建立request的時(shí)候直接使用的是NSFetchRequest的純構(gòu)造器方式。
但是在Swift 3.0中首先我們?cè)趧?chuàng)建request的時(shí)候必須用范型來(lái)指定實(shí)際數(shù)據(jù)類型,你可以用如下任何一句來(lái)完成:
let fetch0 = NSFetchRequest<Commit>(entityName: "Commit") let fetch1:NSFetchRequest<Commit> = Commit.fetchRequest()
接下來(lái)在處理fetch結(jié)果的時(shí)候我們不可以將NSFetchRequestResult直接轉(zhuǎn)換為[Commit],因?yàn)檫@樣非相關(guān)性的轉(zhuǎn)換總是失敗!作為代替我們使用context的另一個(gè)方法來(lái)完成:
do{
let commits = try managedObjectContext.fetch(fetch)
print("***** \(commits.count) commits *****")
objects = commits
tableView.reloadData()
}catch let error{
print("Fetch failed : \(error.localizedDescription)")
}
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
iOS開發(fā)中Swift 指紋驗(yàn)證功能模塊實(shí)例代碼
本文給大家分享ios調(diào)用touchid代碼塊,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下把2017-03-03
用Swift構(gòu)建一個(gè)簡(jiǎn)單的iOS郵件應(yīng)用的方法
這篇文章主要介紹了用Swift構(gòu)建一個(gè)簡(jiǎn)單的iOS郵件應(yīng)用的方法,包括查看和標(biāo)記已讀等基本的郵件應(yīng)用功能,需要的朋友可以參考下2015-07-07
關(guān)于Swift 4.1中的Codable改進(jìn)詳解
這篇文章主要給大家介紹了關(guān)于Swift 4.1中的Codable改進(jìn)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-02-02
Swift中的類class與結(jié)構(gòu)體struct體學(xué)習(xí)筆記
和C++一樣,Swfit中同時(shí)擁有類與結(jié)構(gòu)體,能夠充分滿足開發(fā)者面向?qū)ο蠛兔嫦蜻^(guò)程編程的需求,這里我們就來(lái)看一下Swift中的類class與結(jié)構(gòu)體struct體學(xué)習(xí)筆記2016-07-07
swift在IOS應(yīng)用圖標(biāo)上添加提醒個(gè)數(shù)的方法
本文是通過(guò)swift語(yǔ)言實(shí)現(xiàn)在應(yīng)用圖標(biāo)右上角添加消息個(gè)數(shù)提醒的功能,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起看下吧2016-08-08

