[Xcode] Xcode 디버깅 가이드

2026. 5. 8. 17:31·Apple/Xcode
728x90
반응형

안녕하세요! 피피아노입니다 🎵

 

이번 포스팅에서는 디버깅을 하는 방법에 대해서 정리를 해보려고 합니다.

 

우선 기본적인 용어부터 정리해보겠습니다.

  • 콘솔(console): Xcode 아래에 뜨는 작은 창. 앱이 찍는 메시지가 나오는 화면
  • 로그(Log): 앱이 실행되면서 남기는 기록(대표적인 예가 print()로 찍는 것)
  • 브레이크 포인트(Breakpoint): 코드의 특정 줄에서 멈추게 하는 장치
  • 디버거(Debugger): 앱을 멈추거나 한 줄씩 실행시키면서 상태를 보는 도구
  • lldb: Xcode에 내장되어 있는 디버거(콘솔에 명령어를 쳐서 사용)
  • 크래시(Crash): 의도치 않게 앱이 종료되는 현상

가장 기본적인 디버깅

가장 기본적인 것은 아마 많은 분들이 코딩을 처음 접할 때 쓰시는 print 함수를 사용하는 것입니다.

let name: String = "피피아노"
print(name) // 콘솔에 "피피아노"가 나옴

주로 print 함수는 특정 변수 값이 뭔지 확인하거나, 특정 함수가 잘 호출되고 있는지 확인할 때 사용합니다.

 

더 똑똑하게 print()를 사용할 수도 있습니다.

print("[\(#fileID): \(#line))] \(#function) - 카드 교환 시도
//[LearnerCard/Card​Exchange​View.swift: 32)] body - 카드 교환 시도

라는 코드를 작성했습니다.

 

이렇게 코드를 작성하면 해당 라인이 실행될 때 내 프로젝트 어디(#fileID)에서 몇 번째 라인(#line)에 어느 함수(#function)에서 발생했는지 확인할 수 있습니다.

  • #fileID: 모듈명/파일명 출력
  • #line: 몇 번째 라인인지 출력
  • #function: 지금 어떤 함수인지 출력

 

"굳이 이렇게 복잡하게 쓰는 이유가 뭐냐"라고 생각할 수도 있지만 앱이 커지고 여러 곳에서 print()를 작성했다면 콘솔 로그에 너무 많은 로그가 올라오기 때문에 어느 파일, 어느 줄에서 출력된 로그인지 확인하기 어렵게 됩니다. 그럴 때 이렇게 코드를 작성해서 디버깅을 하면 훨씬 구분하기가 쉬워집니다.

 

더 자세하게

단순한 문자열이나 숫자가 아니라, 복잡한 클래스 인스턴스나 구조체 내부를 들여다보고 싶을 때는 print()만으로는 부족합니다. 그럴 때는 debugPrint()와 dump()를 사용합니다.

  • debugPrint(): 값의 타입이나 내부 디테일을 더 명확하게 보여줌
  • dump(): 객체의 내부 구조를 계층적으로(Tree 구조) 펼쳐서 보여줌. 배열이나 딕셔너리, 혹은 커스텀 객체의 프로퍼티가 어떻게 구성되어 있는지 파악할 때 유용
struct User {
    let name: String
    let age: Int
}

let user = User(name: "피피아노", age: 25)

print(user)        // User(name: "피피아노", age: 25)
dump(user)         
/* ▿ User
  - name: "피피아노"
  - age: 25 
*/

 

Logger

print()는 간편하지만, 앱을 배포(Release)할 때도 로그가 남을 수 있고 성능에 영향을 줄 수도 있습니다.

 

print()는 단순해 보이지만 내부적으로는 이런 일이 일어나고 있습니다.

  1. 문자열 포맷팅(String interplation 포함)
  2. stdout(표준 출력)에 쓰기 -> I/O 작업
  3. 스레드 동기화 (thread-safe 보장을 위해 락 사용)
  4. Xcode 콘솔로 전송

이런 print()가 루프 안에 있으면 눈에 띄게 느려지는데 극단적으로 아래와 같은 코드가 있다고 하면

for i in 0..<10_000 {
    print("처리 중: \(i)") // 매번 I/O + 락
}

같은 작업을 해도 print() 유무에 따라 비교하면 수십 배 차이가 나기도 합니다.

 

 

그래서 Apple은 iOS 14부터 Logger 라이브러리를 권장하고 있습니다.

Logger를 쓰면 아래와 같은 이점이 있습니다.

  • 카테고리 분류: 로그를 네트워크, UI, DB 등으로 분류해서 콘솔에서 필터링할 수 있음
  • 보안: 민감한 정보(사용자 이름 등)를 로그에서 자동으로 숨겨주는 기능이 있음
  • 성능: print()보다 시스템 자원을 덜 소모함
import OS //안 해주면 에러 남

let logger = Logger(subsystem: "com.myapp.debug", category: "Network")
logger.log("네트워크 요청 시작")
logger.error("에러 발생: \(error.localizedDescription, privacy: .public)")

 

Breakpoint

Breakpoint는 아래 화면처럼 특정 라인(번호)을 클릭하면 파란색 깃발 모양이 생기게 됩니다.

(없애는 방법은 그냥 밖으로 드래그 앤 드랍)

코드를 수정하고 다시 실행하는 과정 없이, 특정 시점에서 앱을 멈추고 상태를 확인할 수 있습니다.

 

BreakpointAction

브레이크포인트를 우클릭하고 Edit Breakpoint -> Condition에 Swift 식을 입력하면 해당 조건에만 멈추도록 설정할 수 있어서 반복문 디버깅에도 유용합니다.

 

BreakpointAction을 쓰면 print() 대신 멈추지 않고 로그만 찍을 수도 있습니다. 이것도 똑같이 Edit Breakpoint에서 Action을 추가하고 Log Message를 선택해서 메시지를 입력하면 됩니다.

 

print()를 안 쓰고 굳이 이걸 쓰는 이유는 조건부로 특정 상황만 잡고 싶거나 자주 호출되는 함수에서 특정 호출만 보고 싶을 때, 성능 저하를 없애고 싶을 때 사용합니다.

 

Exception Breakpoint

앱이 크래시 났을 때 Xcode 화면을 보면 종종 main()같은 이상한 곳을 보여주는 경우가 있습니다. 이건 어디가 크래시 났는지 정확히 못잡은 건데 이럴 때 Exception Breakpoint를 설정해두면 크래시 순간에 정확한 줄을 잡아줍니다.

 

왼쪽 사이드바에서 Breakpoin Navigator -> 하단 + 버튼 -> Exception Breakpoint -> Done 을 눌러서 설정을 할 수 있습니다.

 

LLDB

브레이크 포인트에서 앱이 멈췄을 때, 콘솔창에 명령어를 입력해서 실시간으로 값을 바꾸거나 확인할 수 있습니다.

  • po(print object): 변수의 내용을 출력 (예: po name)
  • p(print): 변수를 컴파일된 결과 형태로 출력
  • v(Vairable): 메모리에 있는 값을 직접 확인함
  • expression(또는 exp): 멈춰있는 상태에서 코드를 실행하거나 변수 값을 강제로 바꿈

감사합니다.

 

잘못된 내용이 있거나 더 좋은 내용 피드백은 언제나 환영합니다!

궁금하신 부분은 댓글로 질문 부탁드립니다! 

728x90
반응형

'Apple > Xcode' 카테고리의 다른 글

[Xcode] Xcode 26의 새로운 기능  (8) 2025.07.16
[Xcode] TDD와 XCTest 살펴보기  (1) 2025.04.16
[Xcode] Xcode 16 pod init 에러 이슈 해결법  (9) 2024.10.11
[Xcode] LLDB 명령어 살펴보기  (1) 2024.08.05
[Xcode] LLDB로 디버깅 해보기  (1) 2024.08.01
'Apple/Xcode' 카테고리의 다른 글
  • [Xcode] Xcode 26의 새로운 기능
  • [Xcode] TDD와 XCTest 살펴보기
  • [Xcode] Xcode 16 pod init 에러 이슈 해결법
  • [Xcode] LLDB 명령어 살펴보기
P_Piano
P_Piano
Apple 생태계 개발자가 되기 위해 학습과 경험을 기록하고 있습니다.
    반응형
    250x250
  • P_Piano
    피피아노의 개발 일지
    P_Piano
  • 전체
    오늘
    어제
    • 분류 전체보기 (230)
      • Apple (148)
        • iOS (25)
        • visionOS (5)
        • Swift (77)
        • UIKit (2)
        • SwiftUI (27)
        • RxSwift (2)
        • Xcode (6)
        • Metal (2)
      • C언어 (5)
      • C++ (8)
      • Dart (1)
      • Python (3)
      • JavaScript (17)
      • Git (1)
      • CS (1)
        • 디자인 패턴 (6)
        • 네트워크 (20)
        • 운영체제 (8)
        • Database (5)
        • 자료구조 (0)
      • IT 지식 (2)
      • IT 뉴스 (4)
      • 경험 (1)
      • 출처 표기 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    visionOS
    이니셜라이저
    코딩테스트
    클래스
    ios
    Xcode
    오블완
    Initializers
    배열
    네트워크
    운영체제
    변수
    비동기
    SWIFT
    디자인패턴
    상속
    프로세스
    Apple
    Vision Pro
    프로퍼티 래퍼
    함수
    swiftUI
    자바스크립트
    티스토리챌린지
    제어문
    wwdc25
    데이터베이스
    스위프트
    연산자
    UIKit
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
P_Piano
[Xcode] Xcode 디버깅 가이드
상단으로

티스토리툴바