메인스레드에서 UI갱신하는 부분 궁금한 점 있습니다.

미해결질문
고번블 프로필

UI를 메인스레드에서 갱신하는 것은 대부분의 운영체제에서 동작하는 방식이기 때문에 이해는 했는데요.

이전 강의인 ImageDownloader에서 보면 이미지 다운로드할 때 downloadTask에서도 결국 클로저(콜백)를 통해서 이미지뷰에 이미지를 넣었잖아요. 그런데 메인스레드에서 갱신하지 않고 클로저에서 직접 이미지뷰에 접근해서 넣었는데 xcode에서는 알림이 뜬 것이 없었고 별 문제 없이 돌아갔습니다.

그런데 이번 강의의 UITableView.reloadData()는 문제가 있다고 나온거고요.

구글 검색해보면 이런식으로 비동기로 데이터를 받아오고 클로저에서 UI를 갱신해야 되는 경우에는 무조건 메인스레드에서 하는게 맞다고 나오기는 하는데요.

ImageDownloader 예제에서는(imageview에 이미지 세팅) 왜 xcode에서 알림이 없는 것인지 궁금합니다. 이런 경고가 없다는 것이 안전하다는 것을 의미하는 것인지도 궁금하고요. 그냥 imageview의 경우에는 이미지만 잘못나올 뿐이니 괜찮을거야를 의미하는 것이고 테이블뷰의 경우에는 모든 데이터가 다 잘못나올 수 있으니(데이터가 아예 안나올 수도 있으니) 알림을 해준 것인지 궁금하네요. 혹시 알고 계신다면 답변 부탁 드리겠습니다.

좋은 강의 해주셔서 감사합니다. (__)

최강사 프로필
최강사 2018.12.02

GCD라는게 있어요. grand central dispatch 라는게 있는데요. 이게 실제 멀티 쓰레드 프로그래밍 할때 사용하는 함수들이거든요. 멀티 쓰레드라고 하면 요즘은 다 폰도 multi core CPU를 쓰자나요. 그러다 보니 뭔가 job을 cpu에 던져줬을대 2개의 CPU라면 예네들이 job을 잘 나눠서 각자 처리 하고 결과를 돌려주면 CPU를 2개 다 사용하니 퍼포먼스가 좋아지겠죠. 하지만 실제 저런 멀티 쓰레드는 프로그래밍을 그렇게 해야지만 CPU가 병렬 처리를 합니다. 실제 octa core cpu를 사서 프로그램을 돌렸는데 왜 8배 빠르지 않냐고 물어본다면, 그 프로그램이 multi thread 프로그래밍을 안했기 때문에 single core 에서 처리 하기 때문이라고 얘기 할수 있죠. 한마디로 octa core라고 8배 빠른건 아니란 얘기죠. multi thread 프로그램이 돼야된단 얘기입니다.

서두가 길었죠. GCD 얘기를 하려다 보니. 근데 요놈이 multi thread 처리를 해주는 라이브러리 예요. 저걸 사용해서 데이터를 받는 다고 쳤을때, 비동기 병렬로 데이타를 받다보니 어느게 먼저 처리가 끝날지 모르죠 백그라운드에서 thread에 분산 되서 처리 할테니까요. GCD 룰대로 코딩해주면 알아서 분산을 처리 하는거죠. 분산 처리하고 나서 결과물이 나왔을때 그 값을 UI에 보여줘야 할꺼 아니예요. 그때 분산되서 만들어졌던 백그라운드 쓰레드에서 main thread 호출을 하지 않고, 바로 UI콜을 하면 실제 에러는 내면서 죽습니다. 절대 main thread를 백그라운드에서 처리 하면안되는 거죠. 나중에 서로 처리 하려다 데드락이 생기거나 데이터가 어떻게 표시를 해야 되는지 순서의 헷깔림 때문에 문제가 생깁니다. 그때 꼭 main thread queue를 호출해서 그걸 통해서 UI을 바꿔야 만하죠. 이정도면 대답은 된것 같은데요.

마지막 단락의 질문에서 왜 안전하지 않다고 경고가 나오지 않냐는 건데요.

대부분의 UIKit library는 내부에서 이걸 처리 하고 있습니다. 그래서 위험하다고 에러가 나지 않는거죠.

reloadData도 제가 알기론 문제 있다고 안나오는걸로 아는데, 직접 보셨다니, 저도 한번 테스트 해봐야 할듯해요.

고번블 프로필
고번블 2018.12.02

json강의 3강 마지막 부분에 보면 xcode에서 reloadData에 'UITableView.reloadData() must be used from main thread only.'이렇게 나오는데, ImageDownloader 마지막 영상에서 downloadTask의 completeHanlder 클로저에 self.imgView.image = UIImage(named:dataTemp) 이렇게 했는데도 reloadData()에서 나온 메시지가 안나오길레 여쭤본겁니다.

reloadData나 imageView에 image 설정하는것이나 결국 UI컨트롤인데 왜 self.imgView.image = UIImage(named:dataTemp) 이 부분에 'must be used from main thread only.'가 안나올까요.

지식공유자 되기
많은 사람들에게 배움의 기회를 주고,
경제적 보상을 받아보세요.
지식공유참여
기업 교육을 위한 인프런
“인프런 비즈니스” 를 통해 모든 팀원이 인프런의 강의들을
자유롭게 학습하는 환경을 제공하세요.
인프런 비즈니스