티스토리 뷰

반응형

[1] NSManagedObjectContext를 여러개 사용하는 경우

CoreData stack

 

보통 앱에서 하나의 managed object context를 사용합니다. (우리가 자주 쓰는 persistentContainer.viewContext)

하지만 여러개의 managed object context를 사용해야할 상황이 있습니다.

시간이 오래걸리는 작업을 viewContext에서 하면 메인쓰레드가 blocking 되는 상황에서요! 

 

 

여러개의 managed object context를 사용할 때 유의할 점이 있습니다. 

Managed Object context A와 Managed Object Context B 가 있다고 가정해볼게요. 

 

그리고 두개의 context에서 모두 persistent store에 저장되어있는 User 정보를 달라는 request를 보낸다면 

 

https://medium.com/@aliakhtar_16369/mastering-in-coredata-part-12-multithreading-concurrency-problem-212a85f37930

 

 

 

persistent store은 두 context에 모두 User 데이터를 보냅니다. 

 

 

 

Managed Object Context A가 User 정보의 count를 2로 업데이트 하고 그 변화를 Persistent Store에 save 했다고 해볼게요.

Managed Object Context B는 이 변경사항에 대해서 모르고 여전히 예전 count값을 가지고 있게 되는 문제가 발생합니다. 

 

 

 

 

 

여러개의 managed object contexts를 쓸 때 각각의 context가 다른 context가 존재하는 지 모르고 있다는 사실을 유의해야합니다!! 

 

 

[2] NSManagedObjectContext를 여러개 사용하는 경우, 필요한 전략

 

이를 해결하기 위해

Core Data가 지원해주는 두 가지 전략이 있는데,

1) notifications

2) parent-child managed object contexts

 

입니다. 

 

2.1 Notification 

 

이 방법은 아래 방법보다 더 옛날 방법(?) 이여서 링크만 첨부할게요.

https://medium.com/@aliakhtar_16369/mastering-in-coredata-part-13-multithreading-concurrency-strategy-notifications-63ef0f110293

 

Mastering In CoreData (Part 13 Multithreading Concurrency Strategy Notifications)

There are two popular strategies that Core Data supports, notifications and parent-child managed object contexts. In this part we will…

medium.com

 

2.2 Parent-child managed object contexts

 

아래 그림과 같이 child managed object context를 만드는 방법입니다.

 

 

child managed object context는 변경사항을 persistent store에 저장하기 위해 parent managed object context에 의존합니다. 

child managed object context는 persistent store coordinator에 접근 할 수 없습니다. 

 

child managed object context가 변경사항을 persistent store에 저장하려고 할 때마다 

변경사항이 parent managed object context로 푸쉬됩니다. 

notification을 사용하여 변경 내용 사항을 parent managed object context에 수동으로 머지 할 필요가 없습니다.

 

 

 

 

그럼 Parent-child managed object contexts를 어떤식으로 사용하게 되는지 살펴볼게요

 

1. 부모 컨텍스트는 MainQueueConcurrencyType입니다. (viewContext는 main 타입입니다.)

 

2. 자식 컨텍스트를 만듭니다. 자식 컨텍스트는 PrivateQueueConcurrencyType이여야합니다. 

 

3. 자식 컨텍스트는 백그라운드 스레드를 사용하는 무거운 작업을 담당합니다.

(자식 컨텍스트가 백그라운드 스레드를 사용하고 있기 때문에 무거운 작업에 의해 메인 스레드가 차단되지 않습니다.)

 

4. 자식 컨텍스트가 작업을 다하면 코어데이터는 자동으로 변경사항들을 부모 컨텍스트에 merge해줍니다. 우리는 단지 자식 컨텍스트의 save함수를 부르기만 하면 됩니다!!!

 

 

 

 

실제 코드로는 이렇게 작성됩니다 :-)

 

 

[3] newBackgroundContext() 

parent-child managed object contexts 보다 조금 더 간단한 전략이 있는데요, 바로 newBackgroundContext() 입니다.

    lazy var backgroundContext: NSManagedObjectContext = {
        return persistentContainer.newBackgroundContext()
    }()

 

newBackgroundContext를 사용하면, 

persistent container가 concurrencyType이 privateQueueConcurrencyType인 NSManagedObjectContext를 만들고 리턴해줍니다. 이 새로운 컨텍스트는 NSPersistentStoreCoordinator와 직접 연결되며 NSManagedObjectContextDidSave을 자동으로 소비하도록(??) 설정됩니다. 

 

 

 

구글링 해보면 이런 사진이 많이 나오는 데요,

 

 

newBackgroundContext() 로 만들어진 private managed object context의 layer가 main의 아래이다!! 라고 말할 수 있는 건지 잘모르겠습니당...!!

 

과연 main의 부모일까요 자식일까요 병렬일까요...?!?! 

문서에는 안나와있는 것 같구

이렇게 출력해보면 둘다 nil 입니다 🥶🥶

print(backgroundContext.parent)
print(persistentContainer.viewContext.parent)

 

 

꽤 믿을만한 Raywenderlich 튜토리얼  에서는 newBackgroundContext() 안쓰고 

childContext를 쓰더라구요....!!! 

  let childContext = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
  childContext.parent = coreDataStack.mainContext

 

 

Reference

위에서 사용한 사진은 모두 여기 미디엄에서 가져왔습니다!! 

너무 친절히 설명해주셔서 감동적인 포스팅들이에요 🥺

 

- Mastering In CoreData (Part 11 Multithreading Concurrency Rules)

https://medium.com/@aliakhtar_16369/mastering-in-coredata-part-11-multithreading-concurrency-rules-70f1f221dbcd


Mastering In CoreData (Part 12 Multithreading Concurrency Problem)

https://medium.com/@aliakhtar_16369/mastering-in-coredata-part-12-multithreading-concurrency-problem-212a85f37930


- Mastering In CoreData (Part 13 Multithreading Concurrency Strategy Notifications) 

 https://medium.com/@aliakhtar_16369/mastering-in-coredata-part-13-multithreading-concurrency-strategy-notifications-63ef0f110293

 

- Mastering In CoreData (Part 14 Multithreading Concurrency Strategy Parent — Child Context)

https://medium.com/@aliakhtar_16369/mastering-in-coredata-part-14-multithreading-concurrency-strategy-parent-child-context-305d986f1ac3

반응형
댓글