IMCAT.DEV
로그인 가입
Swift 중급 문법

Swift 에러 처리 및 예외 처리

Swift 에러 처리 및 예외 처리 — 중급

에러 처리 및 예외 처리

1. 도입 (왜 배워야 하는가)

Swift의 에러 처리 및 예외 처리는 소프트웨어 개발에서 매우 중요한 주제입니다. 실무에서는 다양한 상황에서 에러가 발생할 수 있으며, 이를 적절히 처리하지 않으면 프로그램이 예기치 못한 방식으로 종료되거나 잘못된 데이터를 사용하게 됩니다. 예를 들어, 쇼핑몰 애플리케이션에서 결제 처리 중 네트워크 오류가 발생하면 사용자는 결제를 완료할 수 없게 되고, 이는 고객 경험에 큰 영향을 미칩니다. 따라서, 에러 처리를 통해 안정적인 사용자 경험을 보장하는 것이 중요합니다.

에러 처리를 소홀히 하면 다음과 같은 문제가 발생할 수 있습니다:

  • 프로그램 크래시: 예외가 발생했을 때 적절한 처리가 이루어지지 않으면 프로그램이 비정상 종료될 수 있습니다.
  • 잘못된 데이터 처리: 에러를 무시하고 프로그램이 계속 실행되면 잘못된 데이터를 기반으로 작업을 진행할 수 있습니다.
  • 디버깅 어려움: 에러 처리가 제대로 이루어지지 않으면 문제를 찾고 수정하는 데 어려움을 겪을 수 있습니다.
  • 2. 핵심 개념 설명

    에러 처리의 핵심 개념은 다음과 같습니다.

  • 에러(Error): 프로그램 실행 중 발생할 수 있는 문제를 의미합니다. Swift에서는 Error 프로토콜을 통해 에러를 정의합니다.
  • 예외(Exception): 일반적으로 예상치 못한 상황에서 발생하는 문제를 말합니다. Swift에서는 예외를 처리하기 위해 do-catch 구문을 사용합니다.
  • 옵셔널(Optional): 에러가 발생할 수 있는 값을 처리하기 위해 사용되는 Swift의 특수한 데이터 타입입니다. 값이 없을 수도 있는 상황을 안전하게 처리할 수 있게 도와줍니다.
  • 용어설명
    Error에러를 정의하는 프로토콜
    do-catch에러를 처리하는 구문
    Optional값이 있을 수도, 없을 수도 있는 타입

    3. 기본 코드 예제

    에러를 정의하고 처리하는 기본적인 사용법을 살펴보겠습니다.

    enum MyError: Error {
        case invalidInput
    }
    
    func divideNumbers(_ numerator: Int, _ denominator: Int) throws -> Int {
        guard denominator != 0 else {
            throw MyError.invalidInput
        }
        return numerator / denominator
    }
    
    do {
        let result = try divideNumbers(10, 0)
        print("결과: \(result)")
    } catch MyError.invalidInput {
        print("오류: 0으로 나눌 수 없습니다.")
    } catch {
        print("알 수 없는 오류가 발생했습니다.")
    }

    실행 결과:

    오류: 0으로 나눌 수 없습니다.

    코드 한 줄씩 동작 설명:

    1. enum MyError: Error - 커스텀 에러 타입을 정의합니다.
    2. func divideNumbers - 두 숫자를 나누는 함수를 정의합니다. 0으로 나누는 경우 에러를 발생시킵니다.
    3. guard denominator != 0 - 분모가 0인지 체크하고, 0일 경우 커스텀 에러를 던집니다.
    4. return numerator / denominator - 정상적으로 나누기를 수행합니다.
    5. do { ... } - 에러 발생 가능성이 있는 코드를 실행합니다.
    6. let result = try divideNumbers(10, 0) - 함수 호출 시 에러가 발생할 수 있으므로 try 키워드를 사용합니다.
    7. catch MyError.invalidInput - 특정 에러를 처리합니다.
    8. catch - 알 수 없는 기타 에러를 처리합니다.
    9. 4. 실전 활용 예제

      예제 1: 쇼핑몰의 장바구니 구현

      장바구니에 상품을 추가할 때 재고가 부족한 경우를 처리합니다.

      enum CartError: Error {
          case outOfStock
      }
      
      class Product {
          var name: String
          var stock: Int
          
          init(name: String, stock: Int) {
              self.name = name
              self.stock = stock
          }
          
          func addToCart(quantity: Int) throws {
              guard stock >= quantity else {
                  throw CartError.outOfStock
              }
              stock -= quantity
              print("\(quantity)개 \(name)을(를) 장바구니에 추가했습니다.")
          }
      }
      
      let product = Product(name: "사과", stock: 2)
      
      do {
          try product.addToCart(quantity: 3)
      } catch CartError.outOfStock {
          print("재고가 부족하여 추가할 수 없습니다.")
      }

      상황 설명: 사용자가 장바구니에 3개의 사과를 추가하려 할 때, 재고가 부족한 경우를 처리합니다.

      예제 2: 파일 읽기

      파일을 읽을 때, 파일이 존재하지 않는 경우를 처리합니다.

      func readFile(at path: String) throws -> String {
          let fileManager = FileManager.default
          guard fileManager.fileExists(atPath: path) else {
              throw NSError(domain: "FileError", code: 404, userInfo: [NSLocalizedDescriptionKey: "파일을 찾을 수 없습니다."])
          }
          return "파일 내용"
      }
      
      do {
          let content = try readFile(at: "path/to/file.txt")
          print(content)
      } catch {
          print(error.localizedDescription)
      }

      상황 설명: 지정된 경로에 파일이 존재하지 않을 경우를 처리합니다.

      5. 흔한 실수와 주의사항

      실수 1: 에러를 무시하기

      // 잘못된 코드
      let result = try? divideNumbers(10, 0) // 에러를 무시

      주요 문제: 에러를 무시하면, 나중에 문제가 발생할 수 있습니다.

      실수 2: catch 블록에서 에러를 처리하지 않기

      do {
          try divideNumbers(10, 0)
      } catch {
          // 에러를 처리하지 않음
      }

      주요 문제: 에러를 처리하지 않으면 사용자가 무엇이 잘못되었는지 알 수 없습니다.

      6. 정리

    10. 에러 처리는 안정적인 애플리케이션 개발에 필수적입니다.
    11. do-catch 구문을 사용하여 에러를 안전하게 처리할 수 있습니다.
    12. 커스텀 에러 타입을 정의하여 구체적인 에러를 생성할 수 있습니다.
    13. 에러를 무시하거나 적절히 처리하지 않으면 디버깅이 어려워질 수 있습니다.

다음에 학습하면 좋은 주제: 비동기 프로그래밍과 에러 처리, 옵셔널 체이닝, Swift의 Result 타입.