
Swift 레퍼런스 문서에는 다음과 같이 설명되어있다.
A Swift language feature for designating a type as the entry point for beginning program execution. Instead of writing top-level code, users can use the
@mainattribute on a single type. Libraries and frameworks can then provide custom entry-point behavior through protocols or class inheritance.
@main은 Swift 5.3 버전부터 @UIApplicationMain를 대신해 사용하는 키워드로 공식 문서에서는 top-level code를 작성하는 대신 사용자는 싱글타입에 @main 속성을 사용할 수 있다고 설명한다. 또한 라이브러리와 프레임워크는 프로토콜과 클래스 상속을 통해 앱의 진입점을 커스터마이징할 수 있다고 한다.
For clarity, any executable statement not written within a function body, within a class, or otherwise encapsulated is considered top-level.
스위프트 공식문서에서는 Swift 소스 파일안에서 탑 레벨 코드는 0개 이상의 선언이나 정의 그리고 표현식으로 구성된다고 한다. 함수 내 명령문, 클래스내 명령문 그리고 기타 캡슐화된것 외에는 모두 Top-Level으로 간주된다.
이 탑 레벨 코드에는 두 가지 종류가 있다. 탑 레벨 선언(top-level declarations)과 실행가능한 탑 레벨 코드(excutable top-level code)인데, @main 문서에서 의미하는 탑 레벨 코드는 실행가능한 탑 레벨 코드를 의미하고, 오직 프로그램의 진입점으로서만 허용된다.
위에서 의미하는 탑 레벨 코드는 기존의 진입점을 알려주는 @UIApplicationMain속성이었다는 것을 알 수 있다.

@UIApplicationMain은 UIApplicationMain 함수를 호출하고 해당 클래스의 이름을 델리게이트 클래스의 이름으로 전달한다.
이 함수는 앱 실행에서 중요한 몇 가지의 기능을 수행한다.
해당 함수는 반환타입이 Int32로 명시되어있지만 그 값을 반환하지는 않는다.

스위프트의 프로그램은 소스파일의 시작점 부터 시작해 특별한 구문 없이 잘 작동하게 된다.
근데, 사용자용 앱의 경우 종료될 때 까지 계속해서 실행되고, UIKit이나 AppKit과 같은 사용자 인터페이스 프레임워크는 앱 실행의 복잡성을 처리하여 앱 동작을 정의하기 위한 고급의 API 후크를 제공하게 된다.
이런 프레임워크를 사용하는 개발자는 앱 실행의 문자 그대로 시작점에 대해 신경 쓰거나 상호 작용하지 않는다.
이 두 모델의 문제를 해결하기 위해서, 앱은 프레임워크의 기본 실행 시작점을 시작하기 위해 소량의 "부팅 로딩" 코드가 필요로 하게 된다.
그래서 초반에 Swift가 나왔을 때는 @UIApplicationMain이나 @NSApplicationMain로 부팅로딩을 제공했었다.
근데 이렇게 조금 길고 직관적이지 않은 코드를 사용하기 보단 @main과 같은 더 일반적이고 가벼운 메커니즘을 제공하는 것이 더 이상적이라고 생각해서 만들었다고 한다.
이는 스위프트의 타입 기반의 시스템을 사용하여 문제를 해결하는 패턴에 더 적합하다고 한다. 그리고 프레임워크가 표준 언어 기능을 사용하여 깔끔하고 간단한 진입점을 제공할 수 있게 한다.
정리하자면, @UIApplicationMain 대신 @main 속성을 사용함으로써 타입 기반의 스위프트 코드에서 이상적인 프로그램의 진입점을 알려줄 수 있고, main() 함수는 일반 정적 메서드 이므로 프로토콜에서 확장 또는 기본 클래스로 제공할 수 있다.
[iOS & Swift 5.3+] @main : type기반의 프로그램 진입점
Top-Level Code가 무슨의미지??? - Swift