티스토리 뷰

@main 이란?

@main 은 Swift 5.3 버전 부터 사용하는 키워드다.
Swift5.3 이전 버전에서는 @UIApplicationMain 키워드를 사용했다.

공식 문서에 따르면 @main은 타입 기반의 프로그램 진입점 이라 설명한다.
프로그램 실행을 시작하기 위한 진입점으로 타입을 지정하는 Swift 언어 기능이라 한다.

보통 AppDelegate Class 에서 볼수있는데 AppDelegate는 앱이 시작되는 진입점을 알려주고, 앱의 입력 이벤트를 전달하는 런루프를 생성하는 역할을 한다.

공식문서의 소개를 보면 탑레벨의 코드를 작성하는 대신 사용자는 싱글 타입에 @main 속성을 사용할 수 있다고 설명한다.

Top-Level Code란?

Top-Level Code 에는 선언문(Top-Level Declarations)과 실행 구문(Excutable Top-Level Code)두 가지가 있다.

선언문(Top-Level Declarations)

Top-Level에서 선언문은 모든 Swift Source File에서 사용 가능하다.
변수, 함수 등의 선언문은 전역으로 얼마든지 선언이 가능하며 같은 모듈 내에서 자유롭게 접근할수 있다.

실행구문(Excutable Top-Level Code)

Top-Level에서 실행문은 선언을 제외한 모든 구문을 의미한다.
실행문의 특징은 Top-Level Entry Point에서만 사용이 가능하다.

@UIApplicationMain

Swift5.3 이전의 버전에서 @main대신 사용되던 키워드다.

Mac템플릿을 생성하면 기본적으로 main.swift 파일을 포함하여 main함수를 쉽게 찾아볼수 있다.

하지만 Xcode에서 새로운 iOS프로젝트를 만들고 앱이 어디서 부터 시작되는지 알기 위해 main 함수를 찾아보려고했으나 찾지못했다.

이유는 iOS기본 템플릿에는 Swift파일에 @UIApplicationMain 을 포함함으로써 컴파일러가 iOS의 진입점을 합성하기 때문에 main.Swift 파일이 필요하지 않았던 것이다.

그렇다고 main()함수가 없는것은 아니다. iOS프로젝트 에서는 UIKit프레임워크가 이를 숨겨서 관리한다.

UIApplicationMain()

Declaration

func UIApplicationMain(
    _ argc: Int32,
    _ argv: UnsafeMutablePointer<UnsafeMutablePointer<CChar>?>,
    _ principalClassName: String?,
    _ delegateClassName: String?
) -> Int32

@UIApplicationMain은 UIApplicationMain()함수를 호출하고 해당 클래스의 이름을 delegateClass의 이름으로 전달한다.

UIApplicationMain()함수는 앱 실행에서 중요한 기능들을 수행하게 된다.

  • 앱의 본체에 해당하는 객체 UIApplication 객체를 생성하고, 앱의 LifeCycle을 관리하게 된다.
  • @UIApplicationMain 으로 지정된 클래스에서 delegate를 인스턴스화 하고 이를 앱의 객체에 할당한다.
  • 앱의 Run Loop를 포함한 기본 이벤트처리 루프를 설정하고 이벤트 처리를 시작한다.
  • 앱의 info.plist에 불러올 main nib파일이 제대로 명시되어 있으면 해당 nib을 불러오게 된다.

앱을 실행하기 위한 제일 중요한 부분들이 여기에서 실행되고 있던것이다.

@main

Swift의 프로그램은 소스파일의 시작점부터 시작해 특별한 구문 없이 잘작동 하게 된다.

사용자용 앱의 경우 종료될 때 까지 게속해서 실행되고, UIKit이나 AppKit과 같은 사용자 인터페이스 프레임워크는 앱 실행의 복잡성을 처리하여 앱 동작을 정의하기 위한 고급의 API후크를 제공하게된다.

이런 프레임워크를 사용하는 개발자는 앱 실행의 문자 그대로 시작점에 대해 신경 쓰거나 상호 작용하지 않는다.

이 두 모델의 문제를 해결하기 위해서 앱은 프레임워크의 기본 실행 시작점을 시작하기 위해 소량의 부팅 로딩 코드가 필요로 하게 된다.

Swift가 나왔을적 초반에는 @UIApplicationMain 이나 @NSApplicationMain 로 부팅로딩을 제공했다고 한다.

하지만 길고 직관적이지 않은 코드를 사용하기 보다 @main 과같이 더일반적이고 가벼운 메커니즘을 제공하는 것이 더 이상적이라고 생각해서 만들었다고 한다.

이는 스위프트의 타입 기반의 시스템을 사용하여 문제를 해결하는 패턴에 더 적합하다고 한다. 그리고 프레임워크가 표준 언어 기능을 사용하여 깔끔하고 간단한 진입점을 제공할 수 있게 한다.

정리해보자

@Main에 대해서 설명하시오.

@main이란 Swift라는 타입 기반 프로그램의 진입점 으로 Top-LevelCode 를 작성하는 대신 사용할수 있습니다.
일반적으로 AppDelegat class의 위쪽에 작성되어있습니다.

main 공식문서

자세한 설명

타입 기반 프로그래밍 & 절차 지향 프로그래밍

우리가 playground 를 사용할 때는 시작점이 어딘지를 정해줄 필요가 없다. 왜냐하면 순차적으로 실행되는 절차 지향 프로그래밍이기 때문이다.

그런데 우리가 UIKit을 이용해서 앱을 만들 때는 클래스들을 만들지만, 그 클래스를 실행하는 코드가 없다.
그래서 엔트리 포인트를 이용해서 어디서 시작할 지를 알려주어야 한다. 이러한 프로그래밍을 타입기반 프로그래밍이라고 부른다.

주의사항

컴파일러는 @main 과 main.swift 파일 두개만 진입점으로 인식한다.
그런데 둘다 있으면 컴파일 에러를 밷는다. (toplevel 이슈관련 오류라고 뜬다.)

꼬리 질문

@UIApplication 을 사용하던 것과 @main 을 사용하는 것에는 어떠한 차이가 있는지 설명하시오

@main 의 경우 특정 프로토콜을 채택한 객체에서 실행할 수 있습니다. 이러한 특성을 활용해 frameWork 나 library 에서도 프로토콜과 클래스 상속을 통해 static main 메서드를 커스텀 할 수 있습니다.

둘의 차이점에 대한 스택오버플로우

Top Level 코드란 무엇인가?

쉽게 말하자면 전역으로 작성된 코드를 의미합니다.
Top-Level 코드의 종류는 선언문과 실행구문 2가지가 있습니다.

선언문은 모든 Swift Source File에서 사용가능 하며 변수, 함수 등의 선언문은 같은 모듈내에서 자유롭게 접근할수 있습니다.
실행문은 선언을 제외한 모든 구문을 의미합니다.

실행문은 Top-LevelEntry Point 에서만 사용이 가능합니다.

Top-Level Code

앱 런치 타임에 일어나는 일들

엔트리 포인트에서 앱이 시작되며 아래와 같은 순서로 순서로 메서드들을 호출하며 앱의 진행이 나타납니다.


main() 메서드가 호출되며 main은 UIApplicationMain 을 호출합니다.
UI file 들을 로드 한 후 사용자가 작성한 코드들을 application willFinishLaunchingWithOptions 메서드를 실행합니다.
모든 기본적인 초기화가 끝난후 application didFinishLaunchingWithOptions 를 호출하게 됩니다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함