CoreData

CoreData ) Core Data stack에 대해서

JoonSwift 2022. 5. 6. 16:08

Core Data stack은 Core Data의 이점을 모두 가져가며 Core Data를 사용하기 위해 필수적으로 알아야 할 부분이라고 생각됩니다. 이번 포스팅에서는 Core Data stack을 이루고 있는 클래스들을 공식문서를 바탕으로 정리해보도록 하겠습니다! 

 

우선 Core Data stack의 이해를 위해 정리해볼 클래스들을 나열해보자면, 

  • NSManagedObjectModel
  • NSPersistentStoreCoordinator
    • NSPersistentStore
  • NSManagedObjectContext
  • NSPersistentContainer

이정도가 있겠습니다. 하나하나 알아보도록 하겠습니다.

 

NSManagedObjectModel

NSManagedObjectModel, Core Data 앱 개발을 시작할 때, 보통 Data model 파일을 생성하면 .xcdatamodeld 파일을 생성하게 됩니다. 여기에 Entity들을 생성하고, attribute, relationship 등 여러 설정을 별도의 코드 작성 없이 할 수 있는데, 이 .xcdatamodeld 파일을 programmatic하게 표현한 것이 바로 NSManagedObjectModel 클래스 입니다. 

하나 혹은 여러개의 Entity를 가질 수 있고, Entity에는 프로퍼티들이 존재합니다. 이 프로퍼티들이 attributes, relationships 등을 나타내는 클래스들을 가지고 있습니다. 

NSManagedObjectModel을 데이터베이스의 Schema라고 생각하면 편합니다. 물론 Schema보다는 더 넓은 개념이라고 할 수 있습니다. 

Core Data stack의 나머지 부분들은 바로 이 Model을 가지고 Object들을 생성하거나, Property를 저장하고, 데이터를 저장소에 저장하는 과정을 거칩니다. 

 

NSPersistentCoordinator

NSPersistent Coordinator를 알아보기 이전에, NSPersistentStore 클래스를 먼저 알아보도록 하겠습니다.

NSPersistentStore

NSPersistentStore 클래스는 Core Data의 persistent store들을 모두 추상화해둔 클래스입니다. Core Data는 4개의 저장소를 제공하고 있는데, SQLite, Binary, XML(iOS에서는 사용 불가능), In-memory 이렇게 4가지를 가지고 있고, 이들은 각각 다음과 같은 상수로 제공됩니다. 

  • NSSQLiteStoreType : non-atomic store type으로, SQLiteDB를 사용하며, Xcode Core Data 템플릿에서 default로 사용되고 있는 방식입니다.
  • NSXMLStoreType : atomic store type으로, XML 파일을 사용하는 타입입니다. iOS에서는 사용이 불가능하고, memory footprint가 어마어마합니다.
  • NSBinaryStoreType : atomic store type으로, Binary Data file을 사용합니다. 
  • NSInMemoryStoreType : atomic store type으로, 메모리를 사용하는 타입입니다. persistent라는 이름이 잘 어울리지 않게, 앱이 종료되거나, 기기를 꺼버리면 사라지는 형태이지만, 유닛 테스트, 캐싱에 유용하게 사용될 수 있는 타입입니다. 

이제 다시 NSPersistentStoreCoordinator로 돌아오겠습니다. NSPersistentCoordinator의 역할은 Managed Object Model과 Persistent Store을 연결해주는 Bridge 역할을 하는 녀석입니다. 즉, 이 둘을 이어주어 뒤에 나올 NSManagedObjectContext를 도와주는 역할을 합니다. 

NSManagedObjectContext는 NSPersistentStoreCoordinator를 통해 Object graph를 persistent store에 저장할 수 있습니다. 쉽게 말해 NSPersistentStoreCoordinator는 Context와 Model, Persistent Store 사이에서 인터페이스 역할을 해주는 클래스입니다. 그렇기에 Coordinator는 Model을 이해하고, 어떻게 정보를 Persistent Store에게 보낼지, 어떤 Persistent Store에서 fetch해올지에 대해 알고있어야 합니다. 또한, 여러개의 Thread에서 Coordinator를 사용할 수는 없습니다. Coordinator는 operator들을 Serializatize하기 때문입니다.

 

NSManagedObjectContext

NSManagedObjectContext는 Managed object들의 변화를 추적하고, 다루기 위한 object 공간입니다. Core Data를 다룰 때, 가장 많이 사용되는 클래스이기도 합니다. 

NSManagedObjectContext는 메모리에서 Object의 변화를 관찰하고, 다양한 처리를 하는 기능을 담당하고 있습니다. 그렇기 때문에 우리가 Managed object에 어떤 변화를 주어도 context를 통해 save() 메서드를 호출하지 않으면, persistent store에는 아무련 영향을 주지 않는것입니다. 

또한 Context는 Object들의 Lifecycle을 관리합니다. 이 관리를 통해 Validation, inverse relationship handling과 같은 다양한 좋은 기능들을 할 수 있는 권한이 주어집니다. 

그리고 Context는 Thread-safe하지 않습니다.

 

NSPersistentContainer

NSPersistentConatiner는 Core Data stack을 캡슐화한 Container입니다. Core Data stack의 모든 요소들의 코드를 작성하는데에 들어가는 시간을 줄여주고, NSPersistentContainer를 선언하여, persistent store들을 load 해주면 끝나는 아주 편리한 클래스 입니다.

private lazy var storeContainer: NSPersistentContainer = {
  let container = NSPersistentContainer(name: self.modelName)
  container.loadPersistentStores { _, error in
    if let error = error as NSError? {
    	//some error message!
    }
  }
  return container
}()

 이런식으로 사용될 수 있습니다. 

 

그렇게 제가 이해한바로 Core Data stack을 그림으로 나타내보면...

이런식으로 구성되어 동작하는 것으로 이해했습니다. 

 

정리

각각의 클래스에 대한 명확한 이해나 어떤 기능이 있는지에 대해 100% 이해하지는 못했지만, Core Data stack의 구성 클래스, 그들의 대략적인 역할, 흐름 등에 대해서 알아보는 포스팅을 작성하였습니다. 

직접 만들어보며 정리하는 시간을 가져야겠습니다. ㅎㅎㅎ

 

참고 문서

https://developer.apple.com/documentation/coredata/core_data_stack

 

Apple Developer Documentation

 

developer.apple.com

 

제가 잘못이해하고있는 부분이나 틀린 부분이 있다면 댓글에 남겨주시면 정말 감사하겠습니다! 🙏