티스토리 뷰

반응형

1. 문제

뷰컨트롤러에 텍스트 뷰를 올려주세요. 

 

 

그리고 앱이 launch 된 지 5분후에 만개의 데이터를 만들고 저장하는 코어 데이터 연산을 해보겠습니다. 

 

 

CoreDataManager는 이렇게 구성되어있습니다.

 

 

그러면 텍스트를 타이핑하다가 5초 후에 CoreData 연산이 시작되면 아무리 타이핑을 입력해도 입력이 안됩니다. UI 담당인 메인 쓰레드가 blocking 되었기 때문이죠! 

 

CoreData 연산이 끝나면 다시 타이핑이 가능해집니다. 

 

 

 

그 이유는 무엇일까요...?!?!?! 

우리가 사용한 viewContext가 main queue에서 동작하는 친구이기 때문입니다!! 

 

https://developer.apple.com/documentation/coredata/nspersistentcontainer/1640622-viewcontext

 

 

 

그래서 시간이 오래 걸리는 작업이라면, viewContext 를 사용하면 안됩니다.

사용자의 화면을 blocking 하기 때문이죠!!! 

 

그럼 아래에서 해결 방안을 알아보겠습니다. 

해결 방안 전에 CoreData에 대한 사전 지식이 필요합니다.

 

2. 해결방안을 위한 사전 지식

 

CoreData Stack은 이렇게 생겼는데요,

https://medium.com/flawless-app-stories/cracking-the-tests-for-core-data-15ef893a3fee

 

 

이렇게 여러개의 context를 가질 수 있습니다. 

(여러개의 context에 대해서는 다른 포스팅에서 다뤄보겠습니다!!)

 

애플 공식문서가 아니라 블로그에서 참조한 그림이여서 정확한 그림이 아닐 수 도 있어요!!!

 

 

 

 

NSManagedObjectContext 문서에 보면 이니셜라이저에 concurrency 타입을 설정해주게 되어있는데요,

 

 

이렇게 두가지 타입이 있습니다. 

 

 

그동안 썼던 context는 main이 였는데,

private를 사용하여 해결해볼 것 입니다. 

 

 

 

3.1 해결방안(1) - newBackgroundContext()

 

이렇게 코드를 바꿔주세요 

 

 

newBackgroundContext 메소드를 사용하면, 
persistent container가 concurrencyType이 privateQueueConcurrencyType인 NSManagedObjectContext를 만들고 리턴해줍니다. 

 

 

 

 

돌려보면 isMainTread가 false로 출력되면서

coredata 연산이 시작해도 UI가 안 멈추는 것을 볼 수 있습니다.

 

(그리고 perform 함수를 써줘야지 쓰레드가 바뀌더라구요!!!)

 

 

3.2 해결방안(2) - child Context 

 

혹은 child context를 만들어도 됩니다!

 

 

 

(child context에 대한 자세한 내용은 이 포스팅을 참고해주세요)

 

 

4. 이상한 점 (좀 더 찾아보고 내용 업데이트 해야겠음)

1) 

perform이 아니라 performAndWait를 쓰면 

isMainTread가 true로 출력됨. 

 

 

 

 

 

👉 해결방안 : DispatchQueue.global().async

 

=> 이렇게 하면 isMainTread false로 출력되고 UI blocking도 안됨. 

 

 

 

2)

persistentContainer의 performBackgroundTask 함수를 사용하면 

isMainTread가 false로 출력되는데,

연산이 시작하면 UI가 blocking 됨.

 

 

3)

newBackgroundContext() + performAndWait 은 sync를 보장하는 반면 

 

 

 

 

childContext + performAndWait 은  sync를 보장안함. (?????)

 

 

 

 

SourceCode

https://github.com/eunjin3786/CoreDataConcurrency

 

eunjin3786/CoreDataConcurrency

Contribute to eunjin3786/CoreDataConcurrency development by creating an account on GitHub.

github.com

 

Reference

https://medium.com/@aliakhtar_16369/mastering-in-coredata-part-15-multithreading-concurrency-strategy-parent-child-use-case-1-12a180a6fc34

 

Mastering In CoreData (Part 15 Multithreading Concurrency Strategy Parent — Child Use Case 1)

Solved Real Problem Using Parent-Child Context

medium.com

 

https://code.tutsplus.com/tutorials/core-data-from-scratch-concurrency--cms-22131

 

Core Data from Scratch: Concurrency

If you're developing a small or simple application, then you probably don't see the benefit of running Core Data operations in the background. However, what would happen if you imported hundreds or...

code.tutsplus.com

반응형
댓글