안녕하세요! 집주인의 얼굴천재 박효준입니다!
MainActor를 여기저기 쓰다가 보니 문제가 발생한 부분을 공유드리고자합니다!
가봅시다~~ ᕦ(ò_óˇ)ᕤ
문제 상황

input.sink { [weak self] event in
switch event {
case .viewDidLoad:
do {
self?.fetchMemorialHouse()
try self?.fetchCategory()
self?.output.send(.fetchedMemorialHouseAndCategory)
} catch {
self?.output.send(.fetchedFailure("데이터 로드 중 에러가 발생했습니다."))
MHLogger.error("에러 발생: \\(error.localizedDescription)")
...
}
}.store(in: &cancellables)
}
현재 HomeViewController가 HomeViewModel의 houseName을 참조하고 있다가
fetchMemorialHouseUseCase.execute()가 끝나면 houseName을 업데이트해주고 그때 뷰를 그리는 방식이다.
그런데, UseCase가 잘 동작하고 프로퍼티가 업데이트가 되었는데 왜 화면은 초기값 “” 빈 문자열이 들어갈까 ?
이를 해결해나간 과정을 말해보겠다.
문제 해결
먼저 MainActor로 덕지덕지 붙어있는 코드가 문제라 생각했다.
메소드 자체도 MainActor이고, 내부 Task에서 또 MainActor라고 선언해두었다.
첫 번째로 위 사진 69번째 Task 우측에 있는 @MainActor를 제거해봤는데 결과는 여전했다.
디버깅을 여러 차례 시도한 결과 useCase 동작이 끝나기 전에 self?.output.send(.fetchedMemorialHouseAndCategory) 을 하는 것 같았다.
그래서 함수 자체를 async하게 만들고 Input을 보내는 것도 await에 의해 끝났을 때 처리하는 것으로 바꿔주었다.
private func fetchMemorialHouse() async throws {
let memorialHouse = try await fetchMemorialHouseUseCase.execute()
self.houseName = memorialHouse.name
self.bookCovers = memorialHouse.bookCovers
self.currentBookCovers = memorialHouse.bookCovers
}
private func fetchCategory() async throws {
let categories = try await fetchCategoryUseCase.execute()
self.categories += categories
}
위와 같이 함수는 그냥 async로 동작하게 하고,
이를 호출하는 곳에서 하나의 Task로 묶고 거기서 await 되면 input.send를 하게 하였다.
input.sink { [weak self] event in
switch event {
case .viewDidLoad:
Task {
do {
try await self?.fetchMemorialHouse()
try await self?.fetchCategory()
self?.output.send(.fetchedMemorialHouseAndCategory)
} catch {
self?.output.send(.fetchedFailure("데이터 로드 중 에러가 발생했습니다."))
MHLogger.error("에러 발생: \\(error.localizedDescription)")
}
}
case .selectedCategory(let index):
self?.filterBooks(with: index)
}
}.store(in: &cancellables)

완벼쿠 하네요 ~
무지성 MainActor는 좋지 않다는 것을 알았습니다.
'UIKit' 카테고리의 다른 글
NotificationCenter의 removeObserver를 해야할까? (0) | 2024.12.03 |
---|---|
뷰 그리는 방식에 대한 논의(Factory vs MH커스텀 vs VC에서 설정) (0) | 2024.12.02 |
CollectionViewCell들 간의 Drag & Drop 구현하기 (1) | 2024.12.01 |
CALayer를 사용할 때 발생하는 메모리 크래시 (0) | 2024.11.29 |
런타임 시점에 Constraint를 조절하여 애니메이션 구현하기 (1) | 2024.11.19 |