SwiftUI @Observable에 클로저를 저장하면 EXC_BAD_ACCESS가 발생하는 이유

뭘 하려고 했냐면 iOS 음악 스트리밍 앱을 만들고 있었는데요. NavigationDestination으로 이동하는 상세 화면마다 ViewModel을 두고, API 호출 로직을 클로저로 주입하는 구조를 쓰고 있었어요. 대충 이런 식이었거든요: @Observable final class PlaylistDetailVM { var songs: [Song] = [] var isLoading = false // API 클라이언트의 메서드를 클로저로 주입 private let fetchSongs: (String) async throws -> [Song] private let addToPlaylist: (String, [String]) async throws -> Void init( fetchSongs: @escaping (String) async throws -> [Song], addToPlaylist: @escaping (String, [String]) async throws -> Void ) { self.fetchSongs = fetchSongs self.addToPlaylist = addToPlaylist } } NavigationDestination에서 @State로 VM을 생성하고요: ...

2026년 4월 21일 · 3 분 · Young

SwiftUI 이미지 깜빡임 버그 3개를 하나씩 벗겨낸 과정

문제 상황 음악 스트리밍 앱을 만들고 있었는데요. 앨범 아트워크가 계속 깜빡이는 거예요. 곡이 바뀔 때만이 아니라 같은 곡을 재생하고 있는데도 아트워크가 순간적으로 사라졌다 나타나고요. 특히 풀 플레이어의 blur 배경이 심했어요. “이미지 로딩이 느린가?” 싶어서 캐시를 넣었는데 여전히 깜빡이더라고요. 원인을 파고들었더니 버그가 3개 겹쳐 있었어요. 버그 1: NSCache 조회 순서가 반대 커스텀 CachedAsyncImage를 만들어서 NSCache에 이미지를 저장하고 있었는데요. 문제는 캐시 조회 순서였어요. ...

2026년 4월 21일 · 3 분 · Young