왜 required init?(coder)인가?

피터·2023년 11월 1일
0

안녕하세요 피터입니다 😃

스토리보드나 Xib을 사용하면 화면 디자인을 눈으로 볼 수 있는 형태로 만들 수 있습니다. 그런데 이러한 디자인이 실제 앱에서 작동하기 위해서는 이를 객체화 해야 합니다. init(coder:)는 이러한 과정에서 중요한 역할을 합니다.

XIB와 NIB

  • XIB (Interface Builder XML): Xcode에서 디자인을 할 때 사용하는 XML 형식의 파일입니다. Interface Builder에서 뷰의 구성 및 레이아웃을 시각적으로 만들 수 있습니다.
  • NIB (NeXTSTEP Interface Builder): XIB를 컴파일한 바이너리 형태의 파일입니다. 앱이 실행될 때 실제로 로드되어 객체를 생성하는 데 사용됩니다.

XIB에서 객체로의 변환 과정

  1. 디자인 시간: Xcode에서 Interface Builder를 사용하여 XIB 파일로 화면을 디자인합니다.
  2. 컴파일 시간: 앱을 빌드할 때, XIB 파일이 NIB 파일로 컴파일됩니다.
  3. 런타임: 앱이 실행되면, 필요할 때 NIB 파일이 unarchiving과 deserialization 과정을 통해 실제 객체로 변환됩니다. 이 과정에서 init(coder:) 메서드가 호출됩니다.

💡 unarchiving과 deserialization
1. Unarchiving:
저장된 (아카이브된) 형태의 데이터를 원래의 객체나 데이터 구조로 변환하는 과정입니다.
예를 들면, 스토리보드나 Xib는 컴파일되어 NIB 파일로 아카이브됩니다. 이 NIB 파일을 로드할 때 원래의 객체로 복원하는 과정을 Unarchiving이라고 합니다.
2. Deserialization:
일련의 바이트로 직렬화된 데이터를 다시 원래의 객체나 데이터 구조로 변환하는 과정입니다.
예를 들면, JSON 혹은 XML 같은 형식의 문자열을 앱에서 사용할 수 있는 객체나 데이터 구조로 변환하는 것을 deserialization이라고 합니다.

즉, 둘 다 저장된 형식에서 원래의 형태로 데이터를 변환하는 과정을 의미하지만, unarchiving은 주로 아카이브된 바이너리 데이터의 복원을, deserialization은 주로 문자열 형식의 데이터의 복원을 의미합니다.

required init(coder:)가 필요한 이유

init(coder:) 메서드는 NSCoding 프로토콜을 준수하는 객체에서 요구됩니다. UIView와 UIViewController는 이 프로토콜을 준수하므로 해당 초기화 메서드를 구현해야 합니다. 스토리보드나 XIB로부터 객체를 로드할 때, 시스템은 init(coder:)를 통해 객체를 초기화합니다.

required 키워드는 모든 서브클래스에서 이 초기화 메서드를 구현해야 함을 나타냅니다. 즉, UIView나 UIViewController의 하위 클래스를 만들 때 이 초기화 메서드는 반드시 구현되어야 합니다.

요약하면, 스토리보드나 XIB에서 뷰나 뷰 컨트롤러를 로드할 때, 런타임에서 NIB 파일을 실제 객체로 변환하는 과정에 init(coder:) 메서드가 필요합니다. 그리고 이 메서드는 NSCoding 프로토콜을 준수하기 때문에 필수로 구현되어야 합니다.

왜 실패가능한 초기화일까?

init(coder:)required init?으로 정의되어 있습니다. 이는 실패 가능한 초기화(failable initializer) 입니다. 그렇다면 왜 실패 가능한 초기화인지 알아볼까요?

실패 가능한 초기화 (Failable Initializer)

초기화가 객체를 올바르게 초기화하지 못할 가능성이 있을 때, 실패 가능한 초기화를 사용합니다. 이 초기화는 실패하면 nil을 반환합니다.

init(coder:)에서의 실패 가능성

init(coder:)는 Interface Builder에서 제공하는 저장된 정보를 기반으로 객체를 초기화합니다. 그런데 이 정보가 올바르지 않거나, 예상치 못한 값이 들어있을 경우 객체를 제대로 초기화할 수 없습니다. 예를 들어, 저장된 정보가 특정 클래스의 객체를 의미하는데, 해당 클래스가 앱에 없거나 변경되었다면 초기화가 실패하게 됩니다.

required와 실패 가능한 초기화

required는 모든 하위 클래스에서 해당 초기화를 구현해야 함을 의미합니다. 하지만 초기화가 성공적으로 이루어질지, 실패할지는 알 수 없기 때문에 init(coder:)는 실패 가능한 초기화로 정의되어 있습니다.

결론적으로, init(coder:)는 스토리보드나 XIB로부터 객체를 로드할 때, 제공되는 정보를 기반으로 객체를 초기화하기 때문에 초기화가 실패할 수 있습니다. 그래서 init(coder:)는 실패 가능한 초기화로 정의되어 있으며, 모든 하위 클래스에서 이를 구현해야 하기 때문에 required 키워드가 붙어 있습니다.

이해가 되셨나요? 더 궁금한 점이나 설명이 필요하면 말씀해주세요! 😃

profile
iOS 개발자입니다.

0개의 댓글