CoreData整理
看过几次 core data by tutorials 了,感觉每次用到还想重新看过,又是不整理的锅。
core data by tutorials 7th now reading.
使用自带的core data
Data Model editor
entity
attribute
relationship
func save(name:String) {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Person", in: managedContext)!
let person = NSManagedObject(entity: entity, insertInto: managedContext)
person.setValue(name, forKeyPath: "name")
do {
try managedContext.save()
people.append(person) } catch let error as NSError {
print("Could not save. \(error), \(error.userInfo)") }
}
func fetch() {
//1
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
//2
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Person")
//3
do {
people = try managedContext.fetch(fetchRequest)
}
catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)") }
}
NSManagedObject Subclass
就是model你的数据。
选中 .xcdatamodeld
然后生成 create nsmanagedObject Subclass
。
Core data stack
iOS10 新加 NSPersistentContainer,可以管理下面四个属性
- NSManagedObjectModel,类似表结构,ruantime时候,把 xcdatamodel 编辑的文件初始化成 NSManagedObjectModel
- NSPersistentStore,读取写入存储,sqlite、json、xml、inmemory
- NSPersistentStoreCoordinator,介于 NSManagedObjectModel 和 NSPersistentStore 之间,多一层抽离可消除彼此细节依赖,使 NSManagedObjectModel 不用知道用了什么介质存储数据,只管存就行;而且如果你有多个持久化存储,那么持久化存储协调器向托管上下文提供了一个统一的接口。
- NSManagedObjectContext
- 管理所创建对象的生命周期
- 管理对象必须有相应的context
- 非线程安全,只能在统一线程中创建context和管理对象
2021-02-20 72
class CoreDataStack {
private let modelName: String
init(modelName: String) { self.modelName = modelName }
private lazy var storeContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: self.modelName) container.loadPersistentStores { (storeDescription, error) in if let error = error as NSError? { print("Unresolved error \(error), \(error.userInfo)") } } return container }()
}
lazy var managedContext: NSManagedObjectContext = { return self.storeContainer.viewContext }()
func saveContext () {
guard managedContext.hasChanges else { return }
do { try managedContext.save() }
catch let error as NSError
{print("Unresolved error \(error), \(error.userInfo)") }
}
问题
must specify an inverse relationship
Does every Core Data Relationship have to have an Inverse?
想象一个场景:
- entity 有个 relationship(non optional,并且不能删除 delete rule=deny) r (没有inverse relationship)
- entity set r = oneR
- relationship 删除 oneR
- coredata save
- 一般情况下我们会觉得肯定保存失败,但是结果确实可以。原因就是因为没有inverse,导致relationship变化的时候,并没有reflect到entity上,也就不会触发validation
background managed object context
background managed object context,每次都在 new context 所以全都是异步并发无序
performBackgroundTask,都在一个 context 里,异步但是有序队列
NSPersistentContainer 及 NSFetchedResultsControllerDelegate
persistentStoreCoordinator fetch 的时候不会触发 delegate 方法,调试了半天。
core data xcode debug
xcode scheme
设置中 Run → Arguments → Arguments passed on launch
添加如下配置
-com.apple.CoreData.SQLDebug 1 (1,2,3都可以,显示级别不一样)
-com.apple.CoreData.ConcurrencyDebug 1
-com.apple.CoreData.MigrationDebug 1
参考
core data debuge setting
Core Data. How to swap NSPersistentStores and inform NSFetchedResultsController?
Preload Sqlite data to Core Data
SwiftUI pagination for List object
Core Data Performance: 6 tips you should know
Fetching Remote Data With Core Data Background Context in iOS App
CoreData: CRUD With Concurrency in Swift - Part 2
Closures Capture Semantics: Catch them all!
Using Core Data on Multiple Threads
Functional Swift: Closures { }
Capturing Values In Swift Closures