美文网首页
coreData问题再记录

coreData问题再记录

作者: revolution丶 | 来源:发表于2023-05-04 17:02 被阅读0次

关键词: 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的节约内存优点导致的,即,如果并非真正使用则不完全加载关系,只有当真正使用关系时(比如遍历)才加载.这个只是个推测,仅供参考.
  • 最后,若有错误,恳请斧正。

相关文章

  • CoreData学习问题记录

    1. 使用+ (__kindof NSManagedObject *)insertNewObjectForEnti...

  • CoreData基本使用

    前几天项目里面加入了CoreData,第一次用,记录一下,这里只记录创建项目之后添加的CoreData。demo地...

  • IOS开发之记录用户登陆状态,ios开发用户登陆

    如何记录用户的登陆状态呢? 用我们的CoreData蛮? CoreData适合处理大量的数据,一般和TableVi...

  • CoreData记录1

    CoreData存储字典数组 1:在Entity Attribute中属性类型选择Transformable2: ...

  • 第五篇:CoreData

    CoreData 初识CoreData 基础使用CoreData 高级使用CoreData 使用进阶CoreDat...

  • FMDB实现ORM

    IOS开发者们在使用coreData和sqlite原生接口的问题上争论不休,使用coreData无疑更方便,它也在...

  • CoreData学习

    Coredata第一课 认识coredata 问题 在iOS/Mac中我们有许多方式去持久化存储数据:NSUser...

  • CoreData 使用transformable类型存储数组

    最近项目中要做本地缓存,所以就选择了简单的CoreData进行存储,存储的时候遇到一个问题就是CoreData中无...

  • CoreData的冰山一角

    最近需要将项目的数据存储模式改为CoreData,所以来总结一下遇到的问题以及解决方法 在使用CoreData前,...

  • MG--Swift3.0简单使用CoreData

    问题:什么时候使用CoreData?数据模型之间关系比较简单的时候 如何简单使用CoreData1.创建一个项目勾...

网友评论

      本文标题:coreData问题再记录

      本文链接:https://www.haomeiwen.com/subject/vnvxsdtx.html