[iOS] UINib 그리고 awakeFromNib에 대하여

frogKing·2023년 8월 6일
0
post-thumbnail

개념 정리

UINib

Interface builder nib 파일을 포함하는 객체.

UINib은 메모리에서 Interface builder 파일을 캐싱해놓고 있어 필요할 때 바로 unarchiving 혹은 instantiation 하게 됩니다. 이렇게 하면 앱이 nib 파일의 내용을 인스턴스화할 때 nib file을 로드하는 시간을 줄여 성능이 향상됩니다.

awakeFromNib

Interface builder 아카이브 혹은 nib 파일이 로드된 후 호출되는 메서드로, 모든 outlet과 action이 연결되어있음을 보장된다.

궁금한 점

awakeFromNib 메서드는 NSObject를 상속해야 사용할 수 있다. 그래서 우리가 자주 사용하는 UIView, UITableViewCell 등에서 awakeFromNib을 재정의하여 그 안에서 IBOutlet 객체에 대해 초기화를 해서 사용하곤 한다.

그런데 UIViewController 또한 NSObject를 상속하기 때문에 awakeFromNib을 재정의할 수 있다. 하지만 우리는 viewDidLoad를 재정의하여 그 안에서 IBOutlet 객체에 대해 초기화를 하지 awakeFromNib은 잘 사용하지 않는다.

설사 사용하더라도 다음과 같은 에러를 만나게 된다.

awakeFromNib 메서드가 호출되는 시점에서 IBoutlet과 연결되지 않아 nil이 발생하는 것인데.. 앞에서 awakeFromNib에서 언급했던 모든 outlet과 연결되었을 때 호출된다는 설명과 맞지 않는다. 왜 그런 것일까?

App이 Storyboard에서 scene을 로드할 때 View Controller 같은 top level object nib만 로드한다.

이때, View Controller의 subview 계층의 nib은 로드하지 않고 awakeFromNib() 메세지를 전달하게 된다.

그래서 View Controller에서의 awakeFromNib에서는 IBOutlet, IBAction에 대해 연결되어 있는 상태가 아니기 때문에 nil인 것이다.

subview 계층의 Nib 파일들은 View Controller가 loadView() 메서드를 통해 view에 대한 요청이 있을 때 로드된다

instantiateWithOwner() 메서드를 통해 subview들을 nib으로부터 unarchiving 및 instantiation을 진행하게 되고 이때 subview의 IBOutlet, IBAction이 연결되면서 이때서야 View Controller의 IBOutlet, IBAction에도 연결되게 된다.

이렇게 Nib 로더가 subview들의 Nib 로딩을 마치게 되면 subview들에게 awakeFromNib() 메서드를 호출하게 된다.

마지막으로 instantiateWithOwner() 메서드가 종료되면 viewDidLoad()가 호출된다.

위 이미지는 View Controller의 lifecycle을 나타내고 있다. View Controller awakeFromNib은 init과 loadView 사이에서 호출되고 subviews의 awakeFromNib은 loadView와 viewDidLoad 사이에서 호출되게 된다.

테스트를 위해 재정의된 메서드 안에 print를 찍어보았다. 이야기했던 순서대로 print되는 것을 확인할 수 있다.

profile
내가 이걸 알고 있다고 말할 수 있을까

1개의 댓글

comment-user-thumbnail
2023년 8월 6일

좋은 글 감사합니다. 자주 올게요 :)

답글 달기