iOS/UIKit
UIKit ;; Core Data (1) 정의와 Core Data Stack
may_wonhui
2023. 4. 7. 13:51
Core Data란?
앱 내부에서 모델 계층을 관리하는 데 사용되는 프레임워크이다.
객체를 저장소에 매핑하는 세부 정보를 추상화하여, 데이터베이스를 직접 관리하지 않고도 데이터를 쉽게 저장할 수 있도록 한다.
Persistence를 포함하는 객체 생명 주기와 객체 그래프 관리와 관련된 작업에 대한 일반화되고 자동화된 솔루션을 제공한다.
Core Data는 일반적으로 모델 계층을 지원하기 위해 작성하는 코드의 양을 50-70% 줄인다.
즉, Core Data는 DB 관리를 위해 Apple이 제공하는 프레임워크이다. (Core Data != DB)
사용자는 Core Data를 이용하여 쉽게 앱 내부에 영구적인 데이터를 저장하고 관리할 수 있다!
Core Data Stack
: Swift Core Data를 사용할 때 필요한 개체들의 집합
NSManagedObjectModel, NSManagedContext, NSPersistentCoordinator으로 이루어져 있다.
NSPersistentContainer
: Core Data Stack의 구성을 쉽게 하기 위한 클래스 (iOS 10+)
NSPersistentContainer는 NSManagedObjectModel, NSManagedContext, NSPersistentCoordinator를 관리함으로써 Core Data Stack의 생성 및 관리를 간편하게 한다.
(NSPersistentContainer != 영구 저장소) + 영구 저장소는 기본적으로 SQLite 구조
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "CoreDataPrac")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
Core Data를 사용하는 프로젝트를 생성하면 AppDelegate에 자동으로 상단의 코드가 추가된다.
앱의 (프로젝트명: CoreDataPrac) NSPersistentContainer 만들어 반환합니다. 저장소 생성에 실패하면 error를 반환한다.
persistentContainer는 lazy var로 선언되어 있다.
따라서 해당 NSPersistentContainer 객체가 처음 사용될 때까지 인스턴스화되지 않는다
NSPersistentContainer는 Core Data Stack을 설정하고 데이터를 관리하는 데 필요한 여러 객체를 포함한다. 이러한 객체들은 초기화 과정에서 복잡한 과정을 수행하므로, 선언 시점에서 필요한 모든 객체를 초기화하게 되면 앱의 초기 실행 속도가 느려질 수 있기 때문이다.
persistentContainer가 생성되면, 해당 저장소는 model, context, store coordinator 인스턴스에 대한 참조값을 가진다.
NSManagedObjectModel (Model)
: 앱의 데이터 구조를 정의한다.
모델은 앱에서 사용할 Entity, Property, Relation 등을 정의하는 데 사용되는 객체이다.
모델은 하나 이상의 Entity를 가지고 있고, 각 Entity 객체에는 property가 존재한다.
모델(NSManagedObjectModel)은 NSManagedContext나 NSPersistentContainer에서 사용되기 전에는 변경 가능하지만, 이후에는 변경해서는 안된다.
모델을 수정하기 위해서는 복사본을 만들어 수정한 후, 기존 모델을 삭제해야 한다.
NSManagedContext (Context)
: 관리되는 객체의 변경 사항을 조작하고 추적하는 object space. DB와의 상호작용을 담당한다.
데이터를 앱에 영구적으로 저장하기 위해서는NSManagedContext를 이용하여 데이터 변경 작업을 수행한 뒤에 변경 내용을 영구 저장소에 반영해야 한다.
변경 사항은 Core Data가 해당 컨텍스트를 영구 저장소에 저장할 때까지 Context의 메모리에 남아있다.
데이터를 추가, 삭제, 수정 및 검색할 수 있다.
Concurrency
- Core Data는 스레드 제한 (직렬 큐 사용)을 통해 관리되는 객체를 보호한다.
- 따라서 작업 중인 스레드에서 context를 초기화한 후 다른 스레드로 전달하면 안된다.
- NSPersistentCoordinator에 참조를 전달하여 다른 스레드가 이를 통한 새 context를 생성하는 것은 가능하다.
// MARK: - Core Data Saving support
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
상단의 코드도 마찬가지로 Core Data를 포함하는 프로젝트를 생성하면 AppDelegate에 자동으로 추가된다.
context.hasChanges 함수를 통하여 컨텍스트에 변경이 있을 때만 save() 메서드를 호출하여 영구저장소에 context를 저장한다.
변경 내용이 없으면 save() 메서드를 호출하지 않으므로써 시스템 자원을 낭비하지 않을 수 있는 것이다.
NSPersistentCoordinator (Coordinator)
: 모델을 사용하여 context와 영구 저장소 간의 통신을 지원하는 역할을 한다.
데이터 모델, 영구 저장소, NSManagedContext를 연결하여 앱에서 데이터를 관리할 수 있도록 해준다.
NSManagedContext는 NSPersistentCoordinator을 사용하여 영구 저장소와 연결하며, 변경된 데이터를 저장소에 반영할 때도 NSPersistentCoordinator를 이용한다.
참고
https://developer.apple.com/documentation/coredata/setting_up_a_core_data_stack
https://developer.apple.com/documentation/coredata/nsmanagedobjectmodel
https://developer.apple.com/documentation/coredata/nspersistentstorecoordinator