记 Swift 使用 CoreData 时的一些坑
最近在做一个 App 练手,其中用到了 CoreData 来存储用户的播放列表,由于 CoreData 这部分的文章还是比较少的,所以遇到了不少坑,所以写篇随笔记录一下。
题外话:可以给大家看看这个 App 的界面,我觉得还是挺清新的😄
Preview
P.S. 作为背景的氛围图片用的是 CoreImage 生成的
切入正题。
#0 何时执行保存
起初我认为不用显式执行 Xcode 给我们在 AppDelegate 中生成的 saveContext
函数,因为默认情况下 applicationWillTerminate
会执行 saveContext
,但是我发现这个生命周期函数压根不靠谱,当用户直接从多任务视图将 App 结束掉时这个函数根本来不及执行完毕,导致我们的数据不能及时写入本地数据库中。所以合理的调用时机我认为还是应该在完成一批操作以后就直接执行一次 saveContext
下面简单贴一下我的部分代码吧:
Code Paste 1 Code Paste 2
#1 Relationships 到底什么鬼
另外一个让我很头疼的就是 Relationships,写这块的那天可能有点情绪原因,看苹果官方的 Guideline 看不进去,而且 Google 关于 Relationships 相关的文章也十分少,索性自己闷头研究了。
先说说我遇到了什么问题,我想将属于一个歌单的所有 Song 实体添加到 Playlist 实体的 songs 这个 Relationships 中去,但是发现怎么加都加不进去。我已开始的做法是先用 valueForKey
拿到 songs 属性所代表的 NSManagedObject
,然后强制转换到 NSMutableSet
然后执行添加操作,发现人家压根不鸟我这个操作,虽然没有抛异常,也没有任何 log 打出,但是 “It does NOT work!!!”。
经过一番研究,我发现了 NSManagedObject
有个 mutableSetValueForKey
,才发现当初我真是傻了逼了....
于是用 mutableSetValueForKey
拿到这个 NSMutableSet
顺利执行添加操作并保存,成功了。
#2 Type Conversion From Objective-C to Swift
这块主要是谈谈一些关于类型的一些事。我们知道 Swift 引入了一系列新的数据类型,比如 String
、Int
、Dictionary
、Array
,还有一个神奇的 AnyObject
和 Optional<T>
值。
这里我就直接说了
Swift 中的 String
可以直接作为 NSString 使用,它们之间可以 Toll-Free 转换
Int
、Float
、Double
仍然不是一个标准的 NSObject
对象,所以 KVC 就没有它们什么事,所以我们仍然需要用 NSNumber
包装一下送入 NSManagedObject
,同时拿出来的时候用 xxxValue
取出。
还有,Relationships 一定是 NSSet
类型,不是 NSArray
类型,数据库的关系都是无序的,如果需要有序可以添加一个字段然后查询时用 SortDescription 来排序。
最后,"!"是邪恶符号,慎用。