프로그래밍iOS 개발자

스위프트에서 오류 처리(Error Handling)가 어떻게 작동하는지 설명하세요. 어떤 종류의 오류가 있고, 어떤 방식으로 처리하는 것이 좋으며, 언제 throw/catch를 사용하는 것이 좋고 언제 Result를 사용하는 것이 좋습니까?

Hintsage AI 어시스턴트로 면접 통과

답변.

스위프트는 Error 프로토콜과 throw, try, catch 구문을 통해 엄격한 오류 처리 시스템을 지원합니다. 사용자가 정의한 오류 유형을 Error에서 상속받아 만들 수 있습니다:

enum NetworkError: Error { case noInternet case serverError(code: Int) case unknown }

오류를 던질 수 있는 함수는 throws로 선언됩니다:

func fetchData() throws -> Data { // ... throw NetworkError.noInternet }

오류는 do-catch 블록을 사용해 처리할 수 있습니다:

do { let data = try fetchData() // 데이터 작업 } catch NetworkError.noInternet { print("인터넷 없음") } catch { print("다른 오류: \(error)") }

대체 접근법은 Result<T, Error> 유형을 사용하여 try-catch 없이 결과 또는 오류를 반환할 수 있습니다:

func fetchData() -> Result<Data, NetworkError> { // ... return .failure(.noInternet) } let result = fetchData() switch result { case .success(let data): // OK case .failure(let err): // 오류 처리 }

언제 사용해야 할까요:

  • 오류가 치명적이고 처리하지 않을 수 없는 경우 try/catch를 사용하세요.
  • 비동기 함수이거나 예외 없이 오류를 "외부"로 전달하는 것이 편리한 경우 Result를 사용하세요.

함정이 있는 질문.

질문: "문자열이나 숫자와 같은 모든 유형의 오류를 던지고 잡을 수 있습니까?"

답변: 아니요, 스위프트에서는 Error 프로토콜에 해당하는 유형만 던질 수 있습니다.

// 잘못된 예: throw "StringError" // 컴파일러가 이를 허용하지 않음 // 올바른 예: struct MyError: Error {} throw MyError()

주제의 미묘함으로 인한 실제 오류 사례.


이야기

REST API 클라이언트 프로젝트에서 문자열로 오류를 던졌습니다 (throw "No data"). JavaScript에서는 컴파일되었지만, 스위프트로 변환한 후 치명적인 컴파일 오류가 발생했습니다.


이야기

개발자가 오류를 옵셔널 값으로 반환했습니다 (오류 시 return nil), throw/Result를 사용하지 않았습니다. 그 결과, 오류 세부정보가 손실되어 정확하게 처리하기 어려웠고, Silent fails가 발생했습니다.


이야기

분석 결과 응용 프로그램의 여러 곳에서 동일한 오류가 하나의 Error 유형으로 그룹화되지 않았습니다. 그 결과 응용 프로그램이 동일한 실패를 다르게 처리했고, UI는 동일한 오류에 대해 다른 메시지를 표시했습니다 — 유지 관리와 테스트가 어려웠습니다.