coreData问题再记录

关键词: coreData关联关系无法回显, .relationshipKeyPathsForPrefetching, ***.xcdatamodeld - editor style

背景:最近用swift重玩coreData,略有收获,怕日后忘记,故在此小计.另附demo一份,点击->传送门<-获取

  • 半路添加coreData
    如果新建项目要使用coreData,则新建时勾选即可.但要是老项目准备启用coreData呢,其实也不复杂,两步即可
  1. 新建一个coreData,如图
  2. 在AppDelegate中添加以下代码
    // MARK: - Core Data stack
    lazy var persistentContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name: "CoreDataTest")
        container.loadPersistentStores(completionHandler: { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        })
        return container
    }()

    // MARK: - Core Data Saving support
    func saveContext () {
        let context = persistentContainer.viewContext
        if context.hasChanges {
            do {
                try context.save()
            } catch {
                let nserror = error as NSError
                fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
            }
        }
    }

效果如图


此处要注意:需要将NSPersistentContainer(name: "CoreDataTest")的name换成上方新建的***.xcdatamodeld的名字.
此处persistentContainer方法即操作coreData的容器方法,saveContext方法即为数据库存储方法,拿git来比喻的话就是,context(persistentContainer)方法存取数据是在暂存区活动(git add .) 而saveContext方法就是推远端(git remote)了.

另外需要SceneDelegate的sceneDidEnterBackground方法添加代码

func sceneDidEnterBackground(_ scene: UIScene) {
        // Called as the scene transitions from the foreground to the background.
        // Use this method to save data, release shared resources, and store enough scene-specific state information
        // to restore the scene back to its current state.

        // Save changes in the application's managed object context when the application transitions to the background.
        (UIApplication.shared.delegate as? AppDelegate)?.saveContext()
  }

以确保程序在进入后台是保存数据.至此,半途添加coreData完毕.

  • coreData"替代"model
    coreData可以当做是model来用,
    其中,entities看做类,attributes看做属性.当按箭头选择了响应的Module和Codegen属性后会自动生成实体类的swift文件,只不过这个文件在左侧不显示,但这个类实际是可以像正常类一样被调用的
  let teacher = Teacher(context:context)
  teacher.id = 1
  teacher.subject = "科目1"

另外,对于属性的设置,如图
  1. 如果未选中Optional,则这个属性必须进行赋值才能被coreData存储,否则save方法会报错,也无法存储.
  2. 属性的类型若是整型,如interger 16,则意味这个属性是16位整形数,也就是0到65535,如果对其赋值大于这个数,也是无法save的.
  • 关联关系
    对于关联关系,如图
  1. type属性设置一对多和一对一,如果设置了To Many(一对多)后,可以通过Count来对关联数量做限制,比如minimum=1,maximun=3,则1个teacher实体最多对应3个student,第4个student无法被关联.
  2. 关系的两端的Delete Rule的如果设为deny,则在删除两个有关联的实体时,会报错,这个设计是用来保护数据的,避免删除出错.对于没有影响的关系置为Nullify即可.
  3. 代码添加关联
func allStudentsToTeacherWhosId1() {
        guard teacherArray.count != 0 else {
            return print("先生成老师数据")
        }
        let teacher = teacherArray[0]
        //M1:一对多
        for student in studentArray {
            if let teacherTeahStudentRelationship = teacher.teacherTeahStudents as? NSMutableOrderedSet {
                teacherTeahStudentRelationship.add(student)
                student.stuLearnFromTeacher = teacher
            } else {
                teacher.teacherTeahStudents = NSMutableOrderedSet(object: student)
            }
        }
        //M2:一对一
        let book = WorkBook(context: context)
        book.name = "id1号老师的教案"
        teacher.teacherUseWorkBook = book
        saveData()
        sleep(1)
        getDataShow()
    }

其中如果是一对多的关系,则只能能够用M1的方式处理,关系是个NSMutableOrderedSet(可变集合),所以只能用.add的方法添加.(笔者试过setValueForKey,array.append的方法,都无法添加,添加成功了也没法报存)
一对一则用M2的方式处理,直接赋值即可.
4.如果对两个实体a,b的关联关系设置为:a一对多b,b一对一a,则在代码中a添加b时,重复添加b无效,b只会属于最后一次添加的a实例.而如果a,b的关联关系设置为:a一对多b,b一对多a,则在代码中a添加b时,可以重复添加b,所有a实例的都b.

  • 读取储存的关联关系
  1. 可以通过以下语句在读取实体前预读关联关系(笔者实测,不用加也能读取,要是读取不出来,也可以试试)
let request = Teacher.fetchRequest()
request.relationshipKeyPathsForPrefetching = ["teacherTeahStudents"]
  1. 对于添加成功的关联关系,比如id=1老师对应x学生y学生z学生,
    储存后如果只是读出打印,则无法展示关联数据,如图
    只是读出打印

    而如果是遍历该关系并打印,则可以正常展示.如图
    遍历该关系并打印

    对于这种现象的原因笔者并不确定,搜索后结合推测可能是,coreData的节约内存优点导致的,即,如果并非真正使用则不完全加载关系,只有当真正使用关系时(比如遍历)才加载.这个只是个推测,仅供参考.
  • 最后,若有错误,恳请斧正。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容