프로그래밍iOS/Swift 개발자

스위프트에서 optional chaining 작업의 특징은 무엇이며, 이를 통해 값의 체인을 어떻게 처리하고 어떤 경우에 런타임 오류가 발생할 수 있습니까?

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

답변.

이 질문의 배경:

Optional chaining은 스위프트에서 중첩된 optional 값을 편리하게 다루기 위해 등장했으며, nil 체크 없이도 간결하고 안전한 코드를 작성할 수 있게 합니다. 이는 특히 존재하지 않을 수 있는 객체의 속성이나 메서드를 접근할 때 유용합니다.

문제:

Optional chaining으로 작업할 때, 만약 체인의 객체 중 하나가 nil일 경우 어떤 결과가 나올지 잘못 이해하기 쉽고, 반환 값을 제대로 처리하지 않으면 런타임 오류나 예기치 않은 동작이 발생하게 됩니다.

해결책:

Optional chaining은 nil일 수 있는 객체의 중첩된 속성, 메서드 및 서브스크립트에 안전하게 접근할 수 있는 메커니즘입니다. 체인의 어떤 요소라도 nil이면 전체 표현식은 nil을 반환하고 오류를 발생시키지 않습니다.

코드 예:

class Address { var city: String? } class User { var address: Address? } let user: User? = User() user?.address?.city = "모스크바" if let city = user?.address?.city { print(city) } else { print("도시를 찾을 수 없습니다") }

주요 특징:

  • 체인 중간에 값이 nil일지라도 속성과 메서드에 접근할 수 있습니다.
  • 반환 값은 항상 optional입니다, 대상으로 하는 속성의 타입과 관계없이.
  • 메서드 호출, 서브스크립트 및 할당 용도로 사용할 수 있지만, 처리되지 않은 nil에 대해 신중해야 합니다.

헷갈리게 하는 질문.

객체가 nil일 때 optional chaining을 통해 메서드를 호출하거나 속성을 가져오려고 하면 런타임 오류가 발생합니까?

아니요, 런타임 오류는 발생하지 않습니다. optional chaining을 통해 모든 표현식은 nil을 반환하며, 실행은 오류 없이 중단됩니다.

코드 예:

let email: String? = nil let lowercased = email?.lowercased() // lowercased는 nil이 되고, 오류는 발생하지 않음

중간 객체가 없을 경우 optional chaining을 통한 할당이 이루어지겠습니까?

아니요, 객체나 중간 속성이 nil이면, 할당은 아무런 변화도 일으키지 않으며 메모리를 변경하지 않습니다.

코드 예:

var user: User? = nil user?.address?.city = "카잔" // 아무 일도 발생하지 않음, user는 nil

optional chaining의 결과가 non-optional일 수 있습니까?

아니요, optional chaining을 통한 표현식의 결과는 항상 optional입니다, 원래 속성이 optional이 아닐지라도.

코드 예:

class Test { var number: Int = 10 } let t: Test? = nil let value = t?.number // value: Int? (optional)

일반적인 오류 및 안티 패턴

  • optional 결과를 무시하고 non-optional로 작업하게 되면 컴파일 오류나 논리적 오류가 발생합니다.
  • optional chaining 후 강제 언랩 시도에 대한 오류.
  • 체인이 너무 길고 복잡해져서 읽기 어렵고 디버깅하기 힘듭니다.

실생활 예

부정적 케이스

코드에서 user?.address?.city에 접근하면서 도시가 존재하는지 확인하지 않고 바로 city!를 출력하게 되면, 하나의 링크라도 nil이면 크래시가 발생합니다.

장점:

  • 코드의 간결함

단점:

  • 런타임에서 크래시 발생 가능성이 높음
  • 읽기 어려움

긍정적 케이스

코드에서 user?.address?.city를 확인하기 위해 if let 또는 guard let을 사용하고, 이후에만 값으로 작업합니다.

장점:

  • 안전성 보장
  • 더 명확한 논리

단점:

  • 코드 증가(하지만 안전하게)