본문 바로가기
🍎 iOS/DevNote

[Swift] @main

by @Eddy 2023. 7. 30.
728x90

Notion에 정리한 내용을 옮겨왔다.

요약

  • 기존에는 UIKit과 AppKit의 프레임워크별 entry point 진입을 위한 attribute가 달랐다.(@UIApplicationMain, @NSApplicationMain)
  • 개발자가 크게 신경쓰지 않는 UIApplicationMain과 NSApplicationMain을 범용적이고 간단하게 작성하기 위해 swift 5.2부터 @main attribute로 통합하였다.
  • 즉, @main은 top-level code인 @UIApplicationMain이나 @NSApplicationMain attribute를 호출해 UIKit이나 AppKit 내에 있는 main()를 호출하기 위한 attribute이다.

 

@main을 정리한 이유

  • Swift에서도 디바이스가 앱의 시작 지점을 알기 위해 main함수로 시작되어야 한다.
  • 근데 Swift에서는 main()함수가 없고, @main이라는 attribute만 존재한다.
  • 그렇다면 @main이 main()의 역할을 대행하는 것으로 보이는데, 자세한 내용이 궁금했다.

 

Top-level code

  • Swift 소스파일의 top-level code는 0개 이상의 statements, declarations, expression으로 구성 되어있다.
  • 기본적으로 소스파일의 top-level에서 선언된 변수, 상수, 명명된 선언들은 같은 모듈의 일부인 모든 소스 파일 내에서 접근할 수 있다.
  • 선언에 access-level modifier를 표시해 기본 동작을 Override할 수 있다.
  • top-level code의 2가지 종류로, top-level declarations와 실행 가능한 top-level code가 있다.
    • top-level declarations: 오직 declaration로만 구성되어 있고, 모든 Swift source file에서 허용된다.
    • 실행가능한 top-level code: statements, expresssion, declarations를 포함하고, 오직 프로그램의 top-level entry point로서만 허용된다.
  • 실행 파일을 만들기 위해 compile하는 Swift 코드는, 코드가 파일과 모듈 안에서 어떻게 구성되었는지와 상관없이 top-level entry point을 표시하는 다음 방법 중 하나만을 포함한다.
    • NSApplicationMain attribute
    • UIApplicationMain attribute
    • main.swift
      • top-level code가 없어도 항상 entry point로 간주된다.
      • @main과 함께 사용해선 안 된다.
    • top-level excutable code를 포함하는 파일

 

@UIApplicationMain, @NSApplicationMain, @main의 탄생 이유

  • Swift에서 절차적 코드로 작성할 때에는 특별한 구문 없이도 간단한 swift 프로그램을 만들 수 있다.
  • @UIApplicationMain과 @NSApplicationMain의 탄생 배경
    • 하지만 UIKit이나 AppKit같은 UI 프레임워크는 앱 시작의 복잡성을 처리해 앱 동작을 정의하기 위한 높은 수준의 API hook를 제공한다. 일반적으로 이러한 프레임워크를 사용하는 개발자들은 앱 실행의 literal 시작점을 딱히 신경쓰지도 않고 상호작용 하지도 않는다.
    • UIKit이나 AppKit에서의 문제를 해결하기 위해 Swift는 UIApplicationMain과 NSApplicationMain을 제공해 개발자가 시작 프로세스를 원활히 처리하도록 만들었다.
  • @main의 탄생 배경
    • UIApplicationMain이나 NSApplicationMain처럼 프레임워크별 하드코딩된 어트리뷰트 대신 범용적이고 가벼운 매커니즘(=@main)을 제공하는 게 이상적이다.
      • 프로그램 실행에 대한 타입 기반 접근 방식은 타입 시스템을 통해 문제를 해결하는 Swift의 일반적인 패턴에 적합하다.
      • 프레임워크가 표준 언어 기능을 사용해 깔끔하고 간단한 Entry point API를 제공할 수 있다.

 

@main

  • Swift 5.2부터 구현된 범용적인 엔트리 포인트 제공 기능
    • 5.2버전 미만에서 UIKit은 @UIApplicationMain을, AppKit은 @NSApplicationMain을 사용해 엔트리 포인트를 지정했다.
  • 프로그램 실행 시작에 대한 진입점으로 타입을 지정하기 위한 Swift 언어 기능이다.
  • 프로그램 흐름의 top-level entry point를 포함하고 있음을 가리키기 위해 structure, class, enum 선언에 @main 속성을 사용한다.
  • top-level code를 작성하는 것 대신에, 사용자는 단일 타입의 @main attribute를 사용할 수 있다.
  • 그러면 라이브러리와 프레임워크는 프로토콜이나 클래스 상속을 통해 custom entry-point 동작을 제공할 수 있다. → UIApplicationMain, NSApplicationMain attribute를 일반화한다.

 

@UIApplicationMain

  • 해당 클래스가 Application delegate라는 것을 표현하기 위한 속성
  • UIApplicationMain함수를 호출하고 해당 클래스 이름을 델리게이트 클래스의 이름으로 전달한다.
  • 앱의 본체에 해당하는 UIApplication 객체를 생성하고, 앱의 Life Cycle을 관리한다.
  • @UIApplicationMain이 표시된 클래스에서 Delegate를 인스턴스화 하고 이를 앱의 객체에 할당한다.
  • 앱의 Run Loop를 포함한 기본 이벤트 처리 루프를 설정하고 이벤트 처리를 시작한다.
  • 앱의 info.plist에 불러울 Main nib 파일이 제대로 명시되어 있으면, 해당 nib을 불러온다.

이 외에도 main.swift나 static main() method를 갖는 protocol에 대한 내용 등이 있지만,

실제로 이를 다룰 가능성이 현저히 낮기 때문에 별도로 정리하진 않았다.

 

참고자료

반응형

댓글