Entry Point는 무엇이고 왜 필요할까?
Entry Point?
컴퓨터 프로그래밍에서 Entry Point란, 프로그램 내에서 프로그램 실행이 시작되고, 프로그램이 command line 인자에 접근할 수 있는 지점입니다. 프로그램의 실행을 시작하면, 로더나 OS는 제어를 entry point로 전달하게 됩니다.
간단한 시스템, 주로 인터프리터 언어나, 간단한 실행 포맷, 그리고 부트 로더의 경우는 실행을 첫번째 문장에서 시작합니다. 그리고 이 entry point가 절대 주소 또는 상대 주소로 된 메모리 주소에 있는 경우가 있습니다.
프로그램의 문장 순서대로 실행되지 않는, order-independent 한 프로그램은 실행하기 위해 컴파일 된 여러 파일 사이에서 그 시작 지점을 명시적으로 지정할 필요가 있습니다. 많은 프로그램들이 이렇게 이름이 있는 지점(named point)에서 실행이 시작됩니다. 프로그래밍 언어에 의해 이름 컨벤션이 있는 경우도 있고, 호출자가 지정한 이름인 경우도 있습니다. 대부분의 C 계열 언어들에서는, 이 named point를 main이라 부르기 때문에 entry point가 주로 main function이라 알려진 것입니다.
iOS 애플리케이션의 Entry Point
C 계열 언어인 Swift로 작성된 애플리케이션 또한 main() 함수를 호출함으로써, 또는 문장 순서대로 실행되는 main.swift 파일 의 첫 문장을 실행함으로써 바이너리를 실행하게 됩니다.
CLI 프로젝트에서 main.swift 파일을 작성해 본 적은 있어도, iOS 프로젝트를 작성하면서는 main 함수를 직접 선언하는 경험을 해보지 못했을 것입니다. 그 대신 iOS 템플릿으로 프로젝트를 생성했을 때 자동으로 생성된 구현 중 AppDelegate 라는 클래스에 @main 특성이 붙어 있는 것을 확인한 적은 있을 것입니다!
Swift 5.3에서는 AppKit(@NSApplicationMain)t 과 UIKit(@UIApplicationMain)의 서로 다른 attribute를 통합하기 위해 제너럴한 용도의 @main attribute가 추가되었습니다.
AppDelegate 클래스 선언에 @main 특성을 추가함으로써, 이 클래스를 앱의 entry point로 지정하고 있는 것입니다. 이 특성은 컴파일 시점에 main 함수를 정의하고, 함수의 구현에서 UIApplicationMain 함수 호출의 인자로 AppDelegate 클래스를 전달하게 될 것입니다.
프로그램 실행시 이렇게 내부적으로 선언된 main이 호출되게 되고, main 함수의 호출은 내부적으로 UIApplicationMain 함수를 호출합니다. 이 호출이 UIApplication 인스턴스와 우리가 지정한 AppDelegate 클래스(UIApplicationDelegate의 서브 클래스)의 인스턴스를 app 인스턴스의 delegate로서 생성하게 됩니다.
Storyboard 의 entry point
UI를 스토리보드를 사용하는 타깃의 경우, 첫 화면으로 그릴 화면에 대한 구현이 필요합니다. UIKit은 화면 구성 정보를 찾기 위해 타깃의 프로퍼티 리스트에 명시된 기본 스토리보드를 로드하게 됩니다.
하나의 스토리보드 파일은 여러 scene을 구성할 수 있기 때문에, 여러 개의 scene 중 첫 화면을 결정해야 합니다. 이때 storyboard 파일에 지정된 initialViewController 필드의 값을 사용합니다. 따라서 스토리보드 상의 entry point, storyboard 기반 UI의 entry point 라고 하면 이 initial view controller 를 가리킨다고 할 수 있습니다.
Entry Point가 없으면 어떻게 될까?
Playground 파일과 같이 문장 순서대로(from top to bottom) 실행하는 프로그램의 경우에는 entry point가 첫 문장이기 때문에 별도로 지정할 필요이 정상 동작합니다. 따라서 top level code도 허용됩니다.
그러나 Cocoa Touch 기반 앱(프로그램)의 경우, main 함수의 호출로 UIApplication 인스턴스를 생성합니다. 따라서 진입점이 없으면 이 인스턴스의 생성과 구현된 코드의 실행이 불가능하게 됩니다.
타깃의 기본 스토리보드 파일은 앱의 첫 화면을 결정하므로, 파일의 initial view controller를 지정하지 않으면 앱이 표시할 첫 화면을 구성하지 못해 앱이 실행되더라도 그 기능을 사용할 수 없게 될 것입니다.
@main 을 제거해보자
Undefined symbol: _main
Linker command failed with exit code 1
빌드에 실패합니다. @main 특성이 자동으로 정의하는 _main **함수가 없는데, 링킹을 시도하다가 실패한 것으로 보입니다.
스토리보드에서 entry point을 제거해보자
스토리보드의 entry point, 화살표를 제거하면 xml 파일에서 scene에 연결된 initial view controller 필드가 제거됩니다
이렇게 앱을 실행하면 검은 화면을 표시하면서 다음과 같은 로그를 출력합니다.
Failed to instantiate the default view controller for UIMainStoryboardFile 'Main' - perhaps the designated entry point is not set?
UIMainStoryboardFile 파일인 Main.storyboard 파일에서 시작 화면으로 사용될 기본 view controller를 초기화하지 못했다고 하네요.
storyboard 파일의 scene들은 각각 view controller를 지정하고 있습니다. 앱은 새로운 화면을 표시해야 할 시점에 해당 scene의 UI 정보로 화면을 구성하고, 지정된 UIViewController 인스턴스를 생성해 그 구현을 연결합니다. 따라서 첫 화면으로 사용할 scene을 entry point, initial view controller 로 지정해 주어야 합니다.
번외로, plist 에서 UIMainStoryboardFile 프로퍼티를 이용해 앱이 entry point scene을 찾을 스토리보드 파일을 교체할 수도 있습니다.
'iOS' 카테고리의 다른 글
UIStackView의 arrangedSubviews와 subviews (2) | 2025.01.14 |
---|