스트리밍은 대부분의 브라우저와
Developer 앱에서 사용할 수 있습니다.
-
실행, 분석, 검사: LLDB의 효과적인 디버깅 알아보기
LLDB를 사용하여 코드베이스를 살펴보고 디버깅하는 방법을 알아보세요. 충돌 로그와 백 트레이스를 활용하는 방법과, 동작 및 정교한 중지 조건을 사용하여 구분점을 수퍼차지하는 방법을 공유합니다. 디버깅 경험을 향상하는 데 도움이 될 ‘p' 명령어 및 Swift 6의 최신 기능도 함께 살펴보세요.
챕터
- 0:00 - Introduction
- 0:42 - Agenda
- 1:15 - Debugging as a search problem
- 4:07 - Crashlogs & starting the program
- 7:27 - Breakpoints
- 12:10 - Breakpoint actions
- 15:27 - Help command
- 16:05 - High-firing breakpoints
- 19:24 - The p command
- 25:39 - @DebugDescription macro
- 27:50 - Wrap-up
리소스
관련 비디오
WWDC23
WWDC21
-
다운로드
안녕하세요, 저는 Felipe입니다 Apple Debugging Technologies 팀의 엔지니어죠 이 영상에서는 코드를 손쉽게 탐색하고 버그를 빨리 찾을 수 있는 디버깅 기술에 대해 알아보겠습니다 LLDB는 Xcode와 함께 제공되는 기본 디버거로 언제든 프로그램을 일시 정지하고 변수 상태 검사, 식 평가 등의 작업을 할 수 있습니다 이 영상에서는 LLDB에서 제공하는 주요 도구를 다루면서 신규 기능과 함께 개발자에게 생소할 수 있는 고급 기술을 보여드리겠습니다 먼저 디버거 사용 시 지침이 될 디버깅 모델을 정의해 보겠습니다 그런 다음 충돌 로그를 사용하는 다른 디버깅 방법을 알아보고 중단점 사용 등 프로그램 실행을 일시 정지하는 다양한 방법과, 특정 코딩 패턴과 디버거의 상호작용 방식을 보겠습니다 그리고 프로그램 상태를 검사하는 주요 도구인 `p` 명령을 살펴보겠습니다 마지막으로 Swift 6의 새로운 기능을 소개할 텐데요 디버거에서 데이터 표시 방식을 맞춤화하는 기능입니다 프로그램의 문제를 디버깅할 때는 일반적으로 프로그램에 문제가 생긴 특정 시점을 확인할 수 있습니다 이는 충돌일 수도 있고 잘못된 값이 표시되거나 프로그램 중단일 수도 있습니다 프로그램 실행 시작 후 잘못된 동작이 관찰되는 시점 사이의 어느 부분에서 결함이 있는 코드가 실행된 것입니다 목표는 해당 코드를 찾는 것입니다 버그는 일반적으로 각기 다른 시점에 프로그램 상태를 검사하면 찾을 수 있는데 검사를 할 때마다 문제가 되는 코드에 더욱 가까워집니다 프로그램 상태를 검사하는 기술 중 몇 가지는 아마 친숙하실 겁니다 예를 들면 일부 코드베이스는 로그 구문을 사용합니다 그런 경우에는 로그 파일의 항목을 읽으면 프로그램의 특정 시점을 검사하는 것과 비슷합니다 로그가 충분히 상세하다면 그것만으로도 코드에서 버그를 찾아낼 수 있습니다 로깅하면 유용한 정보를 판단하는 데는 프로그래머의 선견지명이 필요합니다 하지만 앱 진단을 사용자와 개발자 간에 전송하는 것이 강력한 기술이 될 수 있습니다 자주 사용되는 다른 기술은 인쇄 디버깅인데 이는 우리 모두가 첫 번째로 배우는 기술일 겁니다 인쇄 디버깅을 사용하면 프로그램에 인쇄 구문을 삽입하고 코드를 다시 컴파일하고 프로그램을 실행하고 버그를 재현합니다 마지막으로 인쇄된 메시지를 검사합니다 새로운 것을 인쇄해야 하는 경우 전체 과정을 반복합니다 결국에는 버그 수정에 충분한 프로그램 상태를 조사하게 됩니다 하지만 디버깅을 마쳤으면 인쇄 구문을 제거하는 것을 잊지 말아야 합니다 다들 인쇄 구문이 프로덕션에 남아 있었던 재미있는 경험이 있으실 겁니다 이 프로세스는 시간이 많이 걸리고 오류가 발생하기 쉽습니다 이 영상에서 보여드릴 것은 검색 공간을 빠르게 탐색하기 위해 디버거를 사용하는 방법입니다 이를 위해 LLDB에서 제공하는 주요 도구에 대해 이야기합니다 백트레이스 변수 검사 중단점 식 평가입니다 또한 프로그램을 실행할 필요도 없이 문제를 조사하는 데 LLDB가 어떻게 도움이 되는지 설명합니다 디버거를 사용하여 작업할 때 세 가지 작업을 지속적으로 반복합니다 프로그램을 실행하고 흥미로운 지점에서 중단하고 프로그램 상태를 검사하는 것입니다 프로그램을 검사한 후에는 프로그램 실행의 나중 지점으로 진행할 수도 있고 특정 과거 시점을 검사해야 하면 프로그램을 다시 시작하면 됩니다 실행, 중단, 검사의 루프를 효율적으로 반복하는 것이 효과적인 디버깅의 핵심입니다 그럼 실제로 어떻게 되는지 봅시다 대부분의 디버깅 세션은 코드를 컴파일하고 디버거에서 응용 프로그램을 실행하는 것으로 시작합니다 많은 경우에 우리는 Xcode에서 시작 버튼을 누르거나 대상 실행 파일이나 인수를 사용해서 명령어 라인을 통해 LLDB를 시작하기만 하면 됩니다 그러나 문제 디버깅의 첫 단계는 버그를 재현하는 것인데 그것도 LLDB가 도와줄 수 있습니다 응용 프로그램을 시작하지 않아도 되는 기술을 사용해서요 Apple 플랫폼에서는 프로그램이 충돌할 때마다 충돌 발생 시점의 프로그램 상태에 대한 정보가 수집되고 충돌 로그가 생성됩니다 LLDB는 충돌 로그를 사용해서 디버깅 세션과 비슷한 형태로 제시할 수 있습니다 따라서 충돌 발생 이유에 대한 초기 조사를 실시할 수 있습니다 때로는 이 충돌 로그만으로도 버그의 소스를 알아낼 수 있습니다 동료가 저에게 보낸 충돌 로그가 있는데요 그 동료는 다중 플랫폼 동영상 재생 앱인 Destination Video를 테스트하고 있습니다 LLDB로 열어봅시다 충돌 로그를 열려면 파일을 보조 클릭하고 Xcode로 엽니다 그러면 Xcode가 프로젝트 맥락에서 파일을 열고 싶은지 물어봅니다 Destination Video를 선택하겠습니다
이제 Xcode가 LLDB를 사용해서 디버깅 세션을 생성하는데 이때 충돌 시점의 프로그램 상태를 사용합니다 충돌한 행이 강조 표시되는데 코드가 JSON 파일 열기에 실패했음을 알려 주는 것입니다 충돌 바로 직전에 프로그램이 열려고 했던 파일 이름을 로깅했으니 동료에게 로그 파일을 달라고 할 수 있습니다 그런데 프로그램이 어떻게 이 지점에 도달했을까요? 디버거가 이 질문에 답하는 백트레이스라는 도구를 제공합니다 백트레이스는 이 상태를 유발한 함수 호출 또는 스택 프레임의 시퀀스를 설명합니다 각 함수가 어떤 작업을 하고 있었는지 어디에서 호출되었는지 각 함수가 어디로 반환될 예정이었는지를 보여 줍니다
Xcode의 디버그 탐색기에서 현재 백트레이스를 볼 수 있습니다 충돌 당시 프로그램이 어떤 작업을 하고 있었나요? 현재 프레임은 JSON 로딩 함수에 대한 프레임입니다 전 프레임은 동영상 메타데이터를 가져오던 중이었음을 알려 줍니다 이 작업은 프로그램 초기화 중에 수행되었습니다
백트레이스는 프로그램의 제어 흐름을 이해하기에 아주 유용한 도구로 충돌 로그나 일반적인 디버깅 세션에서도 사용할 수 있습니다 충돌 로그와 함께 사용하면 백트레이스는 충돌 이유에 대해 직관력을 기르는 데 도움이 됩니다 이 예에서는 프로그램이 로깅했을 수 있는 정보를 파악하는 데도 충돌 로그가 도움이 되는데 문제를 조사할 또 다른 길을 제공하기 때문입니다 충돌 로그를 가지고 올바른 행 번호를 가져오려면 충돌 로그를 생성한 앱 버전과 동일한 커밋에서 프로젝트를 체크아웃 해야 하고 해당 빌드에 대한 dSYM 번들을 사용할 수 있어야 합니다 dSYM 번들은 ‘기호화: 기본을 넘어‘에서 자세히 다룹니다 Destination Video 빌드를 위한 SwiftUI에 대해 살펴보겠습니다 ‘나중에 보기‘ 목록에 동영상을 추가하는 기능을 만들었습니다 일부 코드 행이 언제 실행되는지 파악하는 것이 목표입니다 LLDB와 중단점이 어떻게 도움이 되는지 알아봅시다 앱의 기본 화면에서 동영상을 선택하면 동영상 콘텐츠의 DetailView가 표시됩니다
이 보기에서 제가 만든 ‘나중에 보기에 추가‘ 버튼을 볼 수 있고 버튼을 클릭하면 텍스트가 변경됩니다
작동 방식을 이해하기 위해 버튼이 생성되는 지점에 중단점을 만들겠습니다 이것이 제가 프로토타입으로 만든 코드이고 버튼 클래스에 대한 생성기 호출이 있습니다 관련된 행 번호를 클릭해서 여기에 중단점을 설정합시다
이제 새로운 중단점이 중단점 탐색기에 표시됩니다 그런데 응용 프로그램을 실행하는 즉시 어떻게 되나 보세요 LLDB가 행 중단점을 세 개의 서로 다른 위치로 변환합니다
이 중단점에서 서로 다른 코드 경로를 통해 멈출 수 있다는 뜻입니다 동영상의 DetailView로 다시 가서 이 가설을 테스트해 보겠습니다
디버거가 프로그램을 중지합니다 Xcode가 프로그램이 중지된 행을 강조 표시했고 버튼의 생성기를 호출하려고 합니다 백트레이스를 검사하여 UI 요소를 구성하는 중첩된 호출의 중앙에 있음을 확인할 수 있습니다
예를 들어 이 프레임은 요소의 세로 스택을 생성합니다 이전 프레임에 포함된 내용을 보겠습니다
이것은 ScrollView를 생성하고 있습니다
우리는 한 중단점에서 멈췄지만 LLDB는 그 행과 관련된 위치를 총 세 개 식별한 것입니다 `breakpoint list` 명령으로 그 위치의 정보를 볼 수 있습니다 70번 행에 설정한 중단점을 설명하면서 해당 중단점과 관련된 세 개의 위치도 설명합니다 행과 열 번호를 사용해서요 목록의 첫 번째 위치는 현재 중지된 위치입니다 버튼의 생성기에 대한 호출이 70번 행에 있습니다 이것을 행과 열 정보에서 관찰할 수 있습니다 하지만 중단점 식별자 즉 ID를 사용할 수도 있습니다
LLDB는 각 중단점 위치에 ID를 지정하는데 지금은 1.1입니다 Xcode가 중단점 행을 강조할 때 사용하는 것과 동일한 ID입니다 목록의 두 번째 중단점은 식별자가 1.2이고 생성기의 첫 번째 인수인 동작 클로저를 참조합니다 버튼을 클릭하면 이 중단점이 트리거될 것입니다 마지막 중단점 위치는 식별자가 1.3이고 생성기 호출에서 후행 클로저를 참조합니다 이 위치는 실제로 다음 행으로 변환됩니다 클로저 본문이 위 행의 중괄호로 시작해도 말이죠 해당 중단점에 도달해 봅시다 이 초기 생성기 호출부터 실행을 계속해 보겠습니다
프로그램이 후행 클로저 내부의 중단점 1.3에서 중지합니다 백트레이스를 통해 전 프레임으로 생성기를 찾습니다
다시 말하면 이 클로저를 호출한 것이 생성기입니다
최종 중단점에 도달하기 위해 ‘나중에 보기에 추가‘를 클릭하죠
다시 한번 멈췄습니다 하지만 이번에는 동작 클로저 내부에서 멈췄습니다 이 예시는 가장 기본적인 중단점도 중단이 흥미로움을 보여 줍니다 같은 행에 세 개의 서로 다른 코드 영역이 있었는데 각기 다른 코드 경로를 통해 도달했습니다 생성기에 대한 호출 생성기가 호출한 후행 클로저 그리고 버튼을 클릭할 때만 호출되는 동작 클로저였죠 클로저를 많이 사용하는 선언적 코드에서 일반적인 시나리오입니다 SwiftUI처럼요 클로저가 언제 호출될지 늘 알 수 있는 것은 아니기 때문에 클로저 본문의 행 중단점은 클로저 일시 정지에 유용합니다 응용 프로그램 일시 정지는 디버깅 주기에서 중요하지만 프로그램 검사와 함께 사용하면 디버깅 경험을 향상할 수 있습니다 예를 들어 UI 요소가 프로그램과 상호작용하는 방법을 보겠습니다 첫 번째 중단점인 버튼 생성기를 호출하는 중단점에 중점을 둡니다 버튼이 생성될 때만 중단하기 위해 마지막 두 개의 중단점 위치는 비활성화하겠습니다
이제 버튼을 클릭하면 UI 업데이트와 중단점이 트리거될 것입니다
LLDB의 `p` 명령으로 나중에 보기 목록의 크기를 검사할 수 있는데 이 내용은 나중에 자세히 살펴보겠습니다
목록에 방금 추가한 동영상이 하나 있습니다 제목도 확인할 수 있습니다
중단/검사 디버깅 주기에서는 같은 명령을 계속 반복해야 하므로 지루할 수 있습니다 중단점 동작의 개념을 사용하여 디버거는 중단점에 도달하면 명령을 실행하여 도움을 줍니다 다른 예로 중단점에 도달할 때마다 나중에 보기 목록의 항목을 인쇄하도록 해봅시다 중단점을 보조 클릭하면 중단점 편집 메뉴가 있습니다 디버거 명령 동작을 추가해 보겠습니다 목록에 가장 최근 동영상이 있으면 이름을 인쇄하는 동작입니다
중단점에 도달한 후에도 실행을 계속할 수도 있습니다
이제 생성기가 호출될 때마다 대기열에 대한 정보를 얻습니다
이것은 디버거를 활용하여 코드를 다시 컴파일하지 않고 정보를 인쇄하는 방법입니다 지금까지 Xcode의 GUI로 디버거와 상호작용했는데 LLDB는 그 대신에 사용할 수 있는 명령어 라인 인터페이스를 제공합니다 이전 예시의 단계를 반복할 텐데 이번에는 명령어 라인을 사용하겠습니다 디버거 명령어 라인에 액세스하려면 응용 프로그램을 일시 정지합니다
이제 `b` 명령으로 중단점을 설정할 수 있습니다 일반적으로 사용하는 `breakpoint set` 명령 대신 사용할 수 있는 짧은 명령이죠
중단점 동작을 추가하는 데도 명령어 라인을 사용할 수 있지만 그렇게 하면 Xcode를 통해 설정한 동작이 덮어써집니다 ‘break command add‘를 사용해서 나중에 보기 목록에 마지막으로 추가된 동영상 이름을 인쇄합니다
이전과 마찬가지로 인쇄 후에 계속 실행됩니다 이 명령은 가장 최근의 중단점에 영향을 미치지만 선택 사항인 중단점 식별자 인수를 제공하면 다른 중단점을 수정할 수 있습니다
LLDB는 모든 명령에 대해 자세한 설명을 제공하는데 help 명령을 사용하면 됩니다 또한 특정 명령의 옵션에 대해서도 도움을 받을 수 있습니다 더 많은 LLDB 기능을 살펴보려면 apropros 명령이 유용합니다 LLDB의 도움말 텍스트에서 키워드를 검색해서 키워드가 설명하는 명령이나 옵션을 반환해 줍니다 예를 들어 백트레이스와 관련된 명령을 검색하면 frame select와 별칭인 f 명령을 찾아줍니다 또한 thread backtrace 명령도 찾습니다 디버깅할 때 여러 번 트리거되는 중단점을 생성하는 경우가 많지만 그중에서 관심이 있는 중단점은 일부입니다 일반적인 예를 들면 중단점이 루프 안에 배치된 경우 모든 반복마다 중단하는 대신 특정 이벤트가 발생할 때만 중단하고자 합니다 자주 트리거되는 중단점을 처리할 수 있는 세 가지 주요 기술을 살펴보겠습니다 이 코드 스니펫은 컬렉션 내의 동영상을 반복하고 원격 위치에 있는 경우 동영상을 로딩하고 처리합니다 우리는 동영상이 매우 길 때만 loadRemoteMedia 함수에서 중단하고 싶을 수 있습니다 그러기 위해서는 행 중단점을 설정하고 중단점 조건으로 수정하면 됩니다 디버거가 프로그램을 중지해야 하는지 결정하는 규칙이죠 명령어 라인에서 break modify 명령을 사용하고 여기에 중단점 ID와 조건을 제공합니다 중단점에서 유효한 모든 코드를 조건 식으로 사용할 수 있습니다 이 예에서는 현재 동영상이 60초보다 길 경우에만 프로그램을 중단하도록 중단점을 수정할 수 있습니다 Xcode에서 중단점을 보조 클릭하고 중단점 편집으로 이동한 다음 조건 필드를 채웁니다 다시 예로 돌아가서 loadRemoteMedia 함수를 실행할 때만 processVideo 호출을 중지하고 싶을 수 있습니다 이 경우에는 다시 한번 행 중단점을 설정하는데 이번에는 중단점 동작을 추가합니다 앞서 변수를 인쇄하기 위해 중단점 동작을 사용했는데 새 중단점을 생성하는 데도 사용할 수 있습니다 `tbreak` 명령을 사용하여 임시 중단점을 만들 수 있는데 임시 중단점은 프로그램이 그 위치에서 1회 중지되게 합니다 이 예에서는 loadRemoteMedia에 자동 계속 중단점을 설정할 수 있는데 processVideo에 임시 중단점을 생성하는 동작을 포함합니다
세 번째 기술은 정해진 횟수만큼 중단점을 무시하고 그 횟수를 넘으면 중지하게 하는 것입니다 예를 들어 컬렉션에서 처음 10개의 동영상을 무시할 수 있습니다 이렇게 하려면 중단점을 수정해야 합니다 이전과 같은 방법이지만 이번에는 --ignore-count 플래그를 사용하죠 Xcode로 같은 옵션을 중단점 편집 인터페이스에서 사용 가능합니다 극단적인 예로 코드 행이 수백만 번 실행되는 경우 이전의 기술은 프로그램 실행 속도를 크게 낮출 수 있습니다 디버거가 여전히 매번 중지하고 계속해야 할지 결정해야 하기 때문입니다 이러한 상황에서는 코드를 다시 컴파일하는 것이 권장됩니다 예를 들어 중지 조건을 계산하고 조건이 참일 때만 실행되는 if 구문 안에 중단점을 설정할 수 있습니다 유용한 요령은 SIGSTOP 신호와 raise 함수를 사용하는 것입니다 이렇게 하면 응용 프로그램에 멈추라고 지시하고 Xcode또는 LLDB를 통해 실행하는 경우 디버거가 마치 중단점에 도달한 것처럼 인계합니다 지금까지 디버깅 주기의 두 가지 구성 요소에 초점을 맞추었습니다 프로그램을 시작하고 흥미로운 지점에서 중단하는 것입니다 하지만 프로그램 상태 검사를 위한 주요 도구만 살펴봤습니다 `p` 명령을 살펴보겠습니다 이전 예에서 `p` 명령을 변수를 살펴보고 식을 평가하는 주요 방법으로 사용했는데 LLDB는 이 작업을 위해 그 외에도 많은 명령을 제공하며 각기 용도가 다릅니다 이러한 도구를 모두 이해하려면 부담스러울 수 있지만 Xcode 15부터는 변수를 검사하거나 식을 평가해야 하는 대부분의 상황에서 `p`를 사용하면 됩니다 이 명령은 ‘do what I mean‘ print 명령의 별칭으로 재편되었습니다 따라서 각기 다른 여러 도구를 하나의 명령으로 결합해서 시간을 절약할 수 있습니다 이 내용은 ‘구조화된 로깅으로 디버깅하기‘에서 자세히 다룹니다 한번 해봅시다 이제 새 동영상을 앱에 추가할 겁니다 그러기 위해서 동영상의 JSON 설명을 편집했습니다 하지만 앱을 시작하는 즉시 충돌이 발생합니다
이것은 새 동영상에서 편집한 JSON 파일입니다 충돌 시점에 디버거가 중지하도록 앱을 시작하겠습니다
콘솔을 살펴보니 Destination Video의 개발자들이 워크플로에 로깅을 사용합니다
마지막으로 로깅된 정보는 동영상의 JSON 파일이 로딩되고 있었다는 것입니다
프로그램이 시작된 시점과 예외가 보고된 시점 사이에 무슨 일이 발생했습니다 이 시점에서 첫 번째로 하면 좋을 일은 JSON loading 함수 호출 바로 전에 중단점을 설정하여 버그에 가까워지는지 확인하는 것입니다 한번 해보죠
로그 메시지를 보조 클릭하면 해당 소스 코드 위치로 빠르게 이동할 수 있습니다
이 함수의 끝에 중단점을 설정해 보겠습니다
이전 시점에 중단해야 하므로 프로그램을 다시 시작하겠습니다 코드는 수정되지 않았기 때문에 재컴파일 없이 control + 클릭으로 재시작하여 시간을 절약합니다
URL과 파일 이름 로컬 변수를 살펴보겠습니다
둘 다 괜찮아 보이네요 변수 뷰어에서 시각화할 수도 있습니다
아니면 소스 코드에서 변수에 마우스를 올려도 됩니다
일부 유형에는 훑어보기 버튼도 있어서 변수에 대한 세부 정보를 추가로 제공합니다
이게 제가 편집한 파일인 것 같네요
JSON loading 함수를 살펴봤는데 제대로 된 것 같습니다 그러니까 버그는 아마 그 후 어딘가에 있을 겁니다 프로그램의 또 다른 부분을 살펴보겠습니다 JSON 디코더를 가져오는 동영상 생성기입니다
제 생각엔 try 구문 중 하나에 문제가 있는 것 같습니다 하지만 동영상 생성기에 대한 모든 호출을 중단하면 문제가 생깁니다
응용 프로그램에 동영상이 너무 많기 때문입니다 다행히도 이것처럼 중단점이 많은 경우를 처리하는 기술을 앞에서 배웠죠 새 동영상이 앱의 12번째 동영상이라는 것을 알고 있으니 이 중단점에 ignore count를 적용할 수 있습니다 그 대신에 새로운 것을 시도해 봅시다 Swift Error 중단점입니다 이러한 유형의 중단점은 LLDB에 Swift Error가 표시되는 즉시 응용 프로그램을 중단하라고 지시합니다
계속을 클릭합니다
프로그램이 Error 중단점에서 멈췄습니다 imageName JSON 키를 디코딩하려던 중이었죠 여기 뭔가 문제가 있습니다 백트레이스를 사용해서 이전 프레임으로 올라가 봅시다 입력 데이터가 있는 곳으로요
저는 프로그래머라 이런 상황에서 코드로 문제를 해결하는데 `p`는 많은 자유를 주죠 프로그래밍을 해서 이 `data` 배열에 imageNames가 몇 개 있는지 알아봅시다
이런, 문자열을 생성해야 하는군요
출력이 너무 많습니다 imageName을 검색해 봅시다
가까워졌지만 출력이 많습니다 숫자 속성을 확인해 보겠습니다
동영상이 13개일 줄 알았는데 imageName이라는 키는 12개입니다 뭔가 잘못됐네요 JSON 파일을 살펴보겠습니다
제가 imageName을 쓸 때 오타를 냈군요 고쳐보겠습니다
됐습니다
이 예를 통해 어떻게 `p` 명령이 변수를 검사하고 복잡한 식을 평가하는지 알아봤습니다 이 명령은 백트레이스의 프레임 안에서 그런 기능을 합니다 복잡한 식을 점진적으로 빌드할 수 있었고 모든 단계에서 즉시 결과를 인쇄할 수 있었습니다 코드를 다시 컴파일하지 않고도 말이죠 이 디버깅 세션은 응용 프로그램의 로그를 향상하는 방법에 대한 인사이트도 주었습니다 그 방법은 JSON 파일에서 누락된 키를 포함하는 것입니다 지금까지 우리가 검사한 대부분의 변수는 매우 간단했습니다 하지만 데이터가 너무 많이 포함된 유형은 디버깅 세션에서 조사하기가 번거롭고 변수 뷰어에 짧은 설명이나 `p` 명령이 있으면 도움이 될 수 있습니다 이러한 유형은 일반적으로 속성이 많거나 컬렉션 내에 자주 저장됩니다 예를 들어 변수 뷰어에 있는 WatchLaterItem의 컬렉션은 수동으로 펼치지 않는 이상 각 항목에 대한 정보를 보여 주지 않습니다 LLDB는 항상 p와 변수 뷰어의 출력을 사용자 지정하는 메커니즘을 제공했습니다 Swift 6에는 이것을 소스 코드에서 바로 행하는 메커니즘이 있습니다 새로운 @DebugDescription 매크로를 사용하면 됩니다 이 매크로로 유형을 주석으로 추가하는 것 외에도 유형을 요약하는 DebugDescription 문자열 속성도 생성해야 합니다 이때 문자열 보간과 저장된 속성을 사용해서 생성해야 합니다 WatchLaterItem 유형에 이 작업을 구현해 보겠습니다 우리의 데이터 구조에는 세 개의 관련 데이터 멤버가 있습니다 동영상, 이름, 목록에 추가된 날짜입니다 먼저 DebugDescription 매크로로 유형을 표시합니다 그런 다음 debugDescription 문자열 계산된 속성을 생성합니다 그리고 이 경우에는 유형의 요약으로 name과 addedOn 날짜를 사용하겠습니다 이제 변수 뷰어를 다시 검사하면 컬렉션의 각 항목에 요약이 표시됩니다
CustomDebugStringConvertible 프로토콜을 사용하셨다면 이 예가 익숙하게 보일 수 있습니다 이 프로토콜을 사용했다면 유형을 `po` 명령으로 인쇄했을 겁니다 그런 경우에는 프로토콜의 구현을 확인합니다 문자열 보간과 계산된 속성만 사용하는 경우 이 프로토콜 대신 매크로를 사용할 수 있습니다 이러한 유형은 디버거와 훨씬 더 잘 통합되며 디버깅을 위해 하나의 명령 즉 `p`에만 집중할 수 있습니다 지금까지 디버깅 주기를 여러 번 거쳤고 디버거를 효과적으로 사용하는 데 필요한 주요 개념을 살펴봤습니다 디버깅이 어떻게 검색 문제로 취급될 수 있는지를 살펴봤습니다 조건부 중단점과 변수 검사를 사용하면 LLDB는 이러한 검색을 효과적으로 수행할 수 있는 강력한 도구입니다 또한 익숙하지 않은 코드베이스를 이해하는 데도 유용한 도구입니다 중단점 동작과 식 평가를 사용하면 코딩 스킬을 활용해 디버깅하면서 코드를 실행할 수 있습니다 그러기 위해 프로젝트를 다시 컴파일하지 않아도 됩니다 오늘 다룬 내용을 적용해서 버그를 훨씬 더 빠르게 찾으실 수 있기를 바랍니다 버그의 근본 원인을 파악한 후에는 시나리오에 대해 전에는 누락했을 테스트 커버리지를 꼭 추가하세요 시청해 주셔서 감사합니다!
-
-
8:09 - WatchLater button
Button(action: { watchLater.toggle(video: video) }) { let inList = watchLater.isInList(video: video) Label(inList ? "In Watch Later" : "Add to Watch Later", systemImage: inList ? "checkmark" : "plus") }
-
12:54 - Printing watch later list information
p watchLater.count p watchLater.last!.name
-
13:45 - Breakpoint actions: Printing name of the most recently added video
p "last video is \(watchLater.last?.name)"
-
14:42 - Breakpoint actions: on the command line
b DetailView.swift:70 break command add p "last video is \(watchLater.last?.name)" continue DONE
-
26:46 - @DebugDescriptio macro example
// Type summaries @DebugDescription struct WatchLaterItem { let video: Video let name: String let addedOn: Date var debugDescription: String { "\(name) - \(addedOn)" } }
-
-
찾고 계신 콘텐츠가 있나요? 위에 주제를 입력하고 원하는 내용을 바로 검색해 보세요.
쿼리를 제출하는 중에 오류가 발생했습니다. 인터넷 연결을 확인하고 다시 시도해 주세요.