[스토리보드 활용 - 2] Xib, Nib과 awakeFromNib


XIB 파일

인터페이스 빌더에서 시각적으로 구성한 사용자 인터페이스 요소들을 XML 형식으로 저장한 것을 말합니다.
이는 컴파일 시 바이너리 형태(Nib)으로 변환되며, Nib은 런타임에 로드됩니다.

예를 들어보겠습니다. 인터페이스 빌더를 사용하여 스토리보드에서 뷰를 구성하려고 할 때, 뷰를 생성하여 컴포넌트를 구성할 수 있습니다.

image

image

이렇게 생성된 뷰는 XIB 파일로, 즉 인터페이스를 XML로 나타낸 파일입니다.

이는 컴파일하면 이전 포스팅에서 배웠던 Nib 파일로 변환되고, 이것이 런타임에 메모리에 올라가게 됩니다.

이때 awakeFromNib 메서드가 호출되면, 그 시점을 해당 객체의 모든 아웃렛 및 액션 연결이 완료된 시점으로 볼 수 있습니다.

그렇다면 이 사이에 과연 무슨 일이 일어나는 것일까요? 🧐


참조

[Apple 공식 문서: Nib Files]

[Apple 공식 문서: Object archiving]


Nib 파일이 로드될 때 일어나는 일

Nib 파일은 저번에 확인했듯이 컴파일된 Xib 파일입니다. 즉 바이너리 파일입니다.

이러한 Nib 파일은 사용자 인터페이스를 구성하는 다양한 요소들을 설명하는 내용을 담고 있습니다.

당연히 프로젝트를 실행하면 화면을 구성하기 위해 이러한 Nib 파일을 사용하게 되겠죠?

런타임에서는, Nib 파일에서 가지고 있는 “다양한 요소들을 설명하는 내용”을 바탕으로 해당하는 객체와 구성을 재현하는 일이 발생합니다. 즉, Nib 파일을 로드하면 해당 코드를 사용하여 객체가 인스턴스화되고, 구성되고, 다른 객체와 연결됩니다.

이 과정은 구체적으로는 다음과 같은 단계를 거치게 됩니다.

1. Nib 파일과 리소스 파일들을 메모리에 로드

Nib 파일의 객체 그래프 원시 데이터가 메모리에 로드되며, 관련된 이미지/사운드 리소스가 Cocoa 캐시에 추가됩니다.

객체 그래프란, 프로그램 내에서 객체들이 서로 어떻게 연결되었는지 나타내는 구조로, 객체 간의 관계 / 계층 구조 / 아웃렛 및 액션과 같은 연결 정보를 가지고 있습니다.

여기서 아카이브(archiving)에 대한 지식이 필요해지게 됩니다.

Object Archiving 이란?

아카이빙(Archiving)은 연관된 객체 그룹을 저장하거나 애플리케이션 간에 전송할 수 있는 형태로 변환하는 과정입니다.

이러한 아카이빙의 최종 결과물인 아카이브(archive)는 객체의 정체성, 캡슐화된 값들, 다른 객체들과의 관계를 기록한 바이트 스트림입니다.

객체의 인스턴스를 아카이브에 포함시키기 위해서는, 클래스가 NSCoding 프로토콜을 참조하고 있어야 합니다.

이러한 정보를 기반으로 다시 생각해보면, Nib 파일 내에 아카이브된 객체 그래프 정보가 담겨있다고 볼 수 있겠네요.

2. Nib 객체 그래프 데이터 언아카이브(unarchive)와 객체의 인스턴스화

로드된 Nib 데이터를 기반으로 언아카이브를 진행하는데, 이를 통해 객체를 새롭게 초기화할 수 있습니다.

image

우리가 사용하는 UIView의 경우 NSCoding을 준수하고 있는데, 따라서 인스턴스를 아카이브화 하거나 언아카이브할 수 있는 것이죠.

NSCoding 프로토콜을 준수하는 모든 객체의 경우 initWithCoder: 메서드를 사용하여 초기화된다고 하는데, Swift에서 이는 init(coder:NSCoder)를 통해 진행되는 것으로 보입니다.

3. Nib 파일 내 객체들 간의 모든 연결 재설정

이 과정에서 아웃렛, 액션 뿐 아니라 File’s Owner, 플레이스홀더 객체들의 연결까지 모두 다시 설정하게 됩니다.

아웃렛의 경우 객체의 적절한 접근자 메서드를 사용하여 연결하게 되는데, 아웃렛이 설정되면 등록된 관찰자들에게 KVO 알림이 생성됩니다. 이 과정은 해당 객체의 awakeFromNib 메서드가 호출되기 전에 발생하며, 모든 객체 간의 연결이 설정되기 전에 발생할 수 있다고 합니다.

액션의 경우 UIControl 객체의 메서드를 사용하여 재설정하게 됩니다.

4. Nib 파일의 적절한 객체에 awakeFromNib 메시지 전송

Nib 로딩 코드에 의해 인터페이스 객체가 인스턴스화 되면, awakeFromNib 메시지를 받게 됩니다.

5. Visible at launch Time 속성이 활성화된 창 표시


결론

즉, 정리하자면 Nib 파일 내부의 객체 그래프를 언아카이브하여 인스턴스를 생성할 수 있고, 인스턴스의 아웃렛, 액션, 플레이스홀더 등을 재설정하여 연결한 뒤 awakeFromNib 메시지가 전송됩니다.

단순히 스토리보드를 설정할 때는 정확한 과정을 알기 힘들었는데, 조금 도움이 된 것 같습니다. 😄