Boost‐SwiftUI‐2025.05.13(화).md - BoostSwiftUI/SwiftUI GitHub Wiki
원본 텍스트 파일
Boost‐SwiftUI‐2024.05.13(화).txt
스터디 시간 및 참여자
- 2025.05.13 화 오후 9:17 ・ 31분 29초
- 권승용 김인환 유정주 이준복
- 클로버노트를 이용해 회의 내용을 기록하고, Claude를 이용해 요약, 편집했습니다.
iOS 개발 스터디 모임 정리
크래시(Crash) 분석 및 해결 전략
크래시의 정의와 영향
- 크래시는 iOS 애플리케이션에서 예기치 않게 종료되는 현상으로 사용자 경험에 치명적 영향을 줌
- 클라이언트 프로그램에서 흔히 발생하는 문제이며 모바일 앱에서는 특히 중요한 이슈
- 사용자 이탈의 주요 원인이 되어 직접적인 비즈니스 손실로 이어짐
- 앱 안정성과 신뢰도에 결정적 영향을 미치므로 우선적으로 해결해야 하는 문제
- 개발자 관점에서는 "암덩어리"로 비유될 만큼 골치 아픈 문제
크래시의 주요 원인
- 메모리 관련 이슈
- 잘못된 메모리 접근 또는 해제된 객체 참조
- 메모리 누수로 인한 시스템 리소스 부족
- 특히 iOS 18 이상에서는 백그라운드 앱 처리 정책 변경으로 인한 메모리 관련 종료 증가
- 데이터 레이스(Race Condition)
- 여러 스레드가 동시에 같은 가변(mutable) 자원에 접근할 때 발생하는 문제
- "도마는 내 거야"라는 비유로 설명된 공유 자원 접근 문제
- 운이 좋으면 데이터 불일치만 발생하지만, 운이 나쁘면 크래시로 이어짐
- 서버와 클라이언트 간 약속 불일치
- 서버에서 예상치 못한 데이터 형식이나 null 값을 내려주는 경우
- API 응답 구조 변경 시 클라이언트 대응이 미흡한 경우
- 옵셔널 처리 미흡으로 인한 강제 언래핑 실패
스레드와 동시성 개념 심화
- 스레드의 본질적 이해
- "니가 부릴 노예의 손 개수"라는 직관적 비유 사용
- 하드웨어적 스레드와 소프트웨어적 스레드의 차이점과 유사점
- 동시에 여러 작업을 처리하는 메커니즘으로 요리사가 분신술을 쓰는 것으로 비유
- 메인 스레드의 특별한 역할
- UI 렌더링과 사용자 상호작용을 담당하는 "특별한 요리사"
- 메인 스레드 블로킹이 사용자 경험에 미치는 치명적 영향
- 무거운 작업은 반드시 백그라운드 스레드로 분리해야 하는 이유
- 공유 자원 관리의 중요성
- "도마"로 비유된 공유 자원에 대한 동시 접근 문제
- 적절한 동기화 없이 공유 자원에 접근할 경우 발생하는 데이터 불일치 현상
- 전통적인 "락(lock)" 메커니즘의 한계와 새로운 접근 방식의 필요성
Swift Concurrency와 액터 모델 활용 사례
실제 크래시 문제 분석 사례
- 광고 표시 로직에서 발생한 간헐적인 크래시
- 버전 7.0.10부터 장기간 지속된 문제로 "암덩어리"로 불림
- 크래시리틱스에서는 감지되지만 개발 환경에서 재현 불가능한 전형적인 사례
- 동일한 로직을 사용하는 두 클래스(수유용/6캔용)에서 동일하게 발생
- 사용자 수가 많아 전체 발생 건수는 적지 않으나 개별 사용자 경험 측면에서는 간헐적 발생
- 재현 시도: 화면 여러 번 호출, 백그라운드에서 호출, 다양한 기기 테스트 등 여러 방법 시도
문제의 핵심 원인 분석
- 광고 로딩 로직의 구조적 결함
- 서버에서 받은 광고 SDK 정보 배열을 순차적으로 처리하는 과정
- 첫 번째 광고부터 시도하여 실패 시 다음 인덱스로 넘어가는 로직
- 광고 SDK 호출 실패 시 다음 인덱스 사용, 모두 실패 시 자체 광고("에브리 타임") 표시
- 메서드들이 비동기로 선언되어 있고 GCD와 혼용되어 복잡성 증가
- 문제의 핵심: 인덱스 값과 배열 값이 모두 가변(mutable)이어서 데이터 레이스 발생
Swift Concurrency와 액터 모델 적용 과정
-
액터 모델의 핵심 개념
- 액터: 순서대로 들어온 태스크를 시리얼하게 처리하는 격리된 환경
- 전통적인 락(lock) 방식과 달리 더 효율적이고 안전한 동시성 처리 방식
- "칼(lock)을 들고 도마를 사용하는" 방식에서 벗어나 구조적으로 안전성 보장
- 메인 액터: UI 관련 작업을 담당하는 특별한 액터
-
리팩토링 방안 검토
- 고려된 두 가지 접근법:
- 클래스 두 개를 각각 액터로 전환하는 방안
- 메인 액터를 사용해 시리얼하게 처리하는 방안
- 장단점 분석:
- 액터를 사용할 경우 완전한 격리 보장되나 변환 작업 복잡
- 메인 액터의 경우 UI 갱신과 연관된 작업이며 처리 작업이 무겁지 않음
- 최종 선택: 메인 액터 마킹 채택
- 호출 부분은 파셜 태스크로 처리되어 백그라운드에서 실행됨
- 무거운 작업이 아니므로 메인 스레드에서 처리해도 성능 문제 없음
- 고려된 두 가지 접근법:
구현 과정의 기술적 도전
- SDK 딜리게이트와의 호환성 문제
- 액터 클래스에 기존 SDK 딜리게이트를 채택할 때 발생하는 충돌 문제
- 해결법:
@MainActor속성과 함께nonisolated키워드를 사용해 딜리게이트 메서드 처리 - 비동기적인 전통적 콜백과 액터 모델의 결합 방식
- 리팩토링의 결과
- 버전 8.1.010부터 크래시 문제 해결 확인
- 실제 코드 변경은 소수의 라인에 불과했으나 문제 해결에 중요
- 스터디를 통한 통찰력으로 데이터 레이스 발생 지점을 정확히 파악
재현 불가능한 크래시 문제 해결 전략
재현 불가능한 크래시의 특성
- 간헐적으로 발생하는 크래시의 어려움
- 개발 환경에서는 절대 재현되지 않는 경우가 많음
- 특정 사용자 환경이나 엣지 케이스에서만 발생
- 특히 배터리, 메모리, 네트워크 상태에 따라 달라지는 경우
- 실제 사례 공유:
- 수면 측정 중 오디오 세션 관련 크래시
- 아이패드에서만 발생하는 화면 회전 중 스크롤 관련 크래시
- 카카오 SDK 관련 단일 실행 보장 문제로 인한 크래시
효과적인 대응 방법
- "기도 메타" 접근법의 현실
- 완벽히 재현 불가능한 문제에 대한 현실적 해결책으로서의 방어 코드
- 코드에 이상이 없어도 발생할 수 있는 크래시(예: UIKit 버그)
- 정확한 원인을 찾지 못해도 패턴을 파악하여 방어적 코드 구현
- 체계적인 문제 해결 접근법
- 배제법(process of elimination) 활용
- 외부 SDK 검토 및 업데이트
- 저전력 모드, 백그라운드 앱 제한 등 시스템 상태 테스트
- 컨티뉴에이션 객체의 미리 할당 문제와 같은 메모리 관리 측면 검토
크래시 분석을 위한 도구 활용
- 크래시리틱스와 같은 모니터링 도구의 중요성
- 사용자 환경에서 발생하는 문제를 수집하는 핵심 도구
- 크래시 발생 위치, 기기 종류, OS 버전 등 다양한 메타데이터 확보
- 시스템 로그 및 디버깅 방법
- 시스템에서 강제 종료되는 경우 크래시 로그로 잡히지 않는 문제
- 메모리 이슈 추적을 위한 접근법
- 외부 SDK와 네이티브 코드의 상호작용 디버깅 방법
개발자 경력 관리 및 성장 전략
개인 성장을 위한 추천 활동
- 동아리와 사이드 프로젝트의 가치
- 회사에서 얻기 어려운 기술적 성장을 동아리에서 추구
- 동아리를 통한 네트워킹과 학습 기회 활용
- 사이드 프로젝트로 포트폴리오 구축
- 효과적인 이력서 작성 전략
- 정기적인 이력서 업데이트의 중요성
- 피드백을 두려워하지 말고 적극적으로 구하기
- UI 설계 능력 증명을 위한 스크린샷 포함
개발 커뮤니티 참여의 중요성
- 스터디 그룹과 기술 커뮤니티 활동
- 사용자 경험 위주의 앱 개발 커뮤니티 참여 가치
- 동료 개발자들과의 경험 공유를 통한 학습
- 실제 문제 해결 사례를 통한 실용적 지식 습득
부록: 개발 환경에서 자주 맞닥뜨리는 문제들
메모리 및 리소스 관리 이슈
- 백그라운드 앱 처리 정책 변화
- iOS 18 이상에서 백그라운드 앱 처리 방식 변화
- 홀드된 유튜브가 일정 시간 후 강제 종료되는 현상
- 저전력 모드에서의 앱 동작 차이
- 오디오 세션 관리의 복잡성
- 자바스크립트와 네이티브 코드에서 동시에 오디오 접근 시 문제
- 오디오 세션 겹침으로 인한 크래시
- 수면 측정 중 장시간 오디오 녹음의 안정성 확보 방법
외부 SDK 통합 관련 문제
- SDK 버전 및 호환성 이슈
- 카카오 SDK의 단일 실행 미보장 문제
- 컨티뉴에이션 객체 할당 문제로 인한 크래시
- SDK 업데이트로 해결 가능한 문제와 그렇지 않은 문제 구분
사용자 행동 예측의 어려움
- 엣지 케이스 관리의 중요성
- 특정 기기(아이패드)에서만 발생하는 문제
- 스크롤 중 화면 회전과 같은 특수한 사용자 행동 패턴
- 예상치 못한 사용자 행동에 대비한 방어적 코딩 전략