내가 만든 스레드에서 UI를 바꿀수 없다는것은 누구나 알것이다. 물론 젖먹이 개발자 시절에 난 몰랐다...
어잿든 내 스레드에서 UI를 바꿀려면 메인스레드를 호출해야 한다. ios 에서는 DispatchQueue.main.async 이 그 역활을 한다.
짐작했겠지만 메인스레드는 새로 만들어지는게 아니므로 당연히 동기적으로 움직인다.
최근까지도 이 사실을 자주 망각했다. 바로 반복문에서 메인스레드를 호출할때였다.
내 스레드에서 메인스레드를 반복문으로 돌릴때는 서로가 따로 놀기 때문에 (내 스레드와 메인스레드가 서로 비동기라서) 메인스레드에서 UI가 아직 변경되지도 않았는데 내 스레드에서 또 호출해 버린다. 이렇게 되면 버벅거리는 현상이 발생한다.
테스트할때서야 버벅거림을 발견하고 짜증내다 아... 하고 숙연해 진적이 한둘이 아니었다.
아래를 보면 스레드에서 ui를 10번 갱신한다.
하지만 apply변수를 뺀다면 10번이 다 갱신 되지 않고 중간에 몇번은 건너뛰어 결국 일부만 실행되는것 처럼 보일것이다.
//스레드 시작
Thread(target: self, selector: #selector(runLoop), object: nil).start()
//스레드 실행 함수
@objc func runLoop() {
var apply = true
var count = 0
while count < 10 {
//메인스레드에서 작업이 완료되었을때만 실행
if apply {
//시작
apply = false
count += 1
DispatchQueue.main.async {
//ui 변경
//...
setNeedsDisplay()
//완료
apply = true
}
}
}
}
쉽게 말해 동기화를 해야 한다는 말이다.
알면서도 실수할수 있으니 항상 유념하자.
도움이 되셨다면~ 정성으로 빚은 저희 앱! 많은 이용 바래요:)
https://meorimal.com/index.html?tab=spaceship
https://meorimal.com/subway.html
'개발 > ios' 카테고리의 다른 글
SwiftUI TextField 에서 placeholder color 변경하기 (0) | 2022.07.29 |
---|---|
UIEdgeInsets 없이 UILabel에 여백 넣기 (0) | 2018.05.08 |
손쉽게 아이폰 앱을 새로 실행 시키는 코드 한줄 (1) | 2018.03.26 |
UIView의 원 테두리가 얇거나 작아보일때... (0) | 2018.01.29 |
NSString을 마치 UILabel인 양 사용하기 (0) | 2017.11.20 |