Publishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates. 에러가 났다. 앱이 종료되지는 않았지만 Xcode에서 확실하게 경고를 주고 있다.
의미는 내가 지금 DispatchQueue를 사용해서 비동기 처리를 하려고 하는데, 코드의 위치가 main thread가 아니라 background thread이라는 것 같다. 난 저 이미지들을 IDLE 상태로 모두 바꿔주는 처리를 한큐에 해버리고 싶은데, 왜 이게 위험하다는걸까 ?
1. Main thread
Main thread 는 오직 하나이며 나머지는 모두 Background Thread 이다.
Cocoa 가 코드를 main thread에서 호출한다. 그리고 대부분의 코드는 main thread에서 실행된다.
유저가 view에서 상호작용을 한것에 대한 처리, 즉 이벤트가 main thread로 전달된다. 즉, 유저와 interface 를 하기 위한 view에 대한 코드는 모두 main thread에서 구현이 되어야 한다고 한다. 그렇다면 MVVM에서 view에 해당되는 처리들은 main thread에게 주는것이 바람직할 것이다.
그런데 내가 지금 DispatchQueue 를 호출해서 background thread를 건드렸다는 건데, 이게 왜 문제가 될까 ?
2. Background thread
iOS의 framework들은 background thread 에서 작동된다. 그리고 가끔씩 delegate 패턴으로 main thread에서 작업을 수행한다.
화면에 바로 나타나지 않는 작업들, 즉 부하가 많이 걸리는 작업들은 background thread에서 실행되어야 app에 치명적인 성능 저하를 방지할 수 있다 !!! 작업은 background thread에게 주고 delegate와 callback함수로 main thread에게 도움을 청해야 한다. main thread가 시간이 많이 걸리는 처리들을 하게 되면, App 의 View가 refresh되는데 오래 걸릴것이고 유저는 인터페이스에 답답함을 느낄것 이다!! (내가 지금 그 상태이다 ㄱ-)
즉, 나의 문제는 - view를 바꾸는 작업을 background에서 하려고 해서 iOS가 경고를 준 것 같다
참고로 global thread (현재 내가 준 global()옵션을 보면 알 수 있다. ) 가 background thread를 의미한다.
3. Background thread를 사용하는 것이 위험한 이유
앱이 실행될 때 main thread와 background thread는 concurrent하게 작업을 수행한다. 그러니까, 어느 시점에 main thread에서 background thread로 넘어가서 코드가 실행될지 예측할 수 없다. background thread의 개입으로 인해서, 프로그램이 순차적으로 실행되는 것이 복잡해지는 문제가 있다.
thread 하나를 우선적으로 처리하고 싶고 다른 thread들에게서 자원의 접근을 방해받고 싶지 않다 !! 라고 하여 lock을 사용하면, lock은 lock대로 문제이다 (...) lock을 걸면 다른 작업들을 수행하지 못하니까 실제 App의 상황에서는 상당한 위험이 될 수 있다.
그렇다면 Background thread를 그럼에도 사용하는 경우는 없을까 ??
4. Background thread를 사용하는 경우
1 ) code 수행시 시간이 너무 오래걸리는 경우
너무 오랜시간 동안 main thread가 한 작업을 수행하다가 막힌 경우 , application이 강제 종료될 수 있다.
2 ) code가 call back은 가능하지만 main thread에 없는 경우
개발자의 의도와 상관없이 코드가 background thread에서 실행되는 경우이다. 이 경우에는 개발자가 사용하려는 함수가 background thread에서 작업이 이루어질 것이라는 것을 알고 명시적으로 background thread를 사용해야 한다.
나의 경우에는 이 문제를 해결하기 위해서 background thread를 사용하지 말아야 겠다는 결론이 나왔다 😅
나는 지금 view의 화면을 갱신해주고 싶은 작업을 하는 것이지 1)과 2)에 해당사항이 없다...
재미있는 thread의 세계 !!! 리눅스 수업들을 때 multi-threading 실험하던게 생각난다. iOS 동기 & 비동기를 조금더 알아보자 😺