서론
iOS가 되던, 안드로이드가 되던 앱개발에 있어서 절대 빠질 수 없는 것 중 하나가 바로 화면간 정보 전달이다. 화면을 아무리 예쁘가 만들고 멋지게 만들어내도 우리가 화면을 전환할 때, 가져가야 할 것들을 가져가지 못하면 그 새로운 화면에는 어떠한 정보도 띄울 수 없을 것이다.
iOS 를 독학하기 시작했을 때부터 여러 방법들을 찾아보고 구글링 해봤지만 어떠한 블로그나 사이트에서도 한번에 깔끔하게 정리해놓은 곳을 찾지 못했다.
내가 부족한 지식이지만 정리를 해보려고한다.
UIViewController 의 구조에 대해 알아보자.
안드로이드, iOS 의 뷰에는 LifeCycle 생명주기가 존재한다.
iOS 뷰의 LifeCycle은 아래 그림과 같다.
우리가 흔히 ViewController을 만들면 기본적으로 생성되어있는 ViewDidLoad() 는 세번째 단계에 해당한다.
그렇다면 LifeCycle의 Load 와 Appear은 어떤 차이가 있을까?
어플리케이션을 켜면, 어플리케이션의 첫 화면이 등장하기까지 짧은 시간이 소요된다. 그 시간동안 어플리케이션은 코드를 처리한다. 그리고 완료된 코드를 바탕으로 View를 띄운다.
즉 View는 그의 해당하는 코드( ViewController )를 처리해준 후 보여준다.
간단한 예로,
이런 간단한 코드가 있다고 하자.
우리는 UILabel 에 This is Shawn 이라는 단어를 띄우고 싶다.
이 ViewController의 코드를 처리해주지 않으면 mainLabel 에는 This is Shawn이 나오지 않을 것이다.
잘 나온 모습이다.
그렇다면 라이프사이클에서, ViewDidLoad 다음인 ViewWillAppear에서
Label에 코드를 추가해주면 어떨까?
결과는 ?
잘 나온다. 자 그럼 이번엔 ViewDidAppear은 어떨까?
이번에도 잘 나온다.
직접 코드로 실행시켜본다면 느끼겠지만, ViewWillAppear이나, ViewDidLoad보다 훨씬 늦게 This is Shawn이 나타나는 것을 알 수 있다.
이처럼 , ViewController 안에 오버라이드 된 생명주기 함수들은 차례로 코드를 처리하며 뷰를 보여준다. ViewDidAppear의 text가 늦게 나타난 이유는 당연히 함수 이름처럼 View가 나타난 이후에 text를 적용시켜주기 때문이다.
사실, 아주 당연해 보이는 이 실험을 해본 이유는 따로있다.
아래처럼, ViewDidLoad에서 text를 적용시키고,
TwoViewController 을 Present 방식으로 띄워보자.
그리고, TwoViewController 안에는 main 이라는 이름의 IBOutlet UILabel 이 있다.
결과는 어떻게될까?
VC.main이 없다는 에러가 뜬다. 우리는 분명 코드에 적어줬는데?
UI와 관련된 객체들은 다른 레퍼런스들과 좀 다른 특성을 띈다.
쓰레드도 Main쓰레드를 사용해야만하고,, 그리고
View가 Load되기 전까지는 없는 객체가 된다.
우리가 버튼을 눌렀을 때, 없는 Label의 text를 적용 시킨 꼴이 된다.
하지만 이렇게 이미 뷰가 present가 된 이후에 코드를 적어주거나,
Completion안에 넣어준다면, text가 잘 적용된 모습을 볼 수 있다.
이것도 마음에 들지 않는다면,
TwoViewController 에 value 를 새로 만든다음 적용 시킨 후
TwoViewController 의 ViewDidLoad에서 새로 적용 시켜주면 된다.