Swift의 3가지 @ 기능

oto·2026년 1월 9일

Swift에서 @를 사용하는 3가지 종류:

1. Attribute (속성)

컴파일러가 직접 제공하는 특수 어노테이션

  @MainActor  // ← Attribute
  final class ViewModel {}

  @available(iOS 15, *)  // ← Attribute
  func newFeature() {}

  @discardableResult  // ← Attribute
  func save() -> Bool {}

  @objc  // ← Attribute
  func handleNotification() {}

  @escaping  // ← Attribute
  var completion: (() -> Void)?

특징:

  • 컴파일러가 직접 제공 (사용자 정의 불가)
  • 컴파일러 동작 제어
  • 타입, 함수, 프로퍼티, 매개변수 등 다양한 곳에 사용

2. Property Wrapper (프로퍼티 래퍼)

사용자가 정의할 수 있는 프로퍼티 접근 패턴

  @propertyWrapper  // ← 정의
  struct UserDefault {
      var wrappedValue: String
  }

  // 사용
  @UserDefault(key: "name")  // ← Property Wrapper
  var name: String

  @Published  // ← Property Wrapper (Combine)
  var state = State()

  @State  // ← Property Wrapper (SwiftUI)
  private var isOn = false

특징:

  • 프로퍼티에만 사용
  • @propertyWrapper로 정의
  • 사용자 정의 가능

3. Macro (매크로)

Swift 5.9+에서 추가된 코드 생성 기능

  @Model  // ← Macro
  final class UserEntity {}

  @Attribute(.unique)  // ← Macro
  var id: String

  @Observable  // ← Macro (Swift 5.9+)
  final class ViewModel {}

특징:

  • 타입, 프로퍼티, 함수 등 다양한 곳에 사용
  • 컴파일 타임 코드 생성
  • 사용자 정의 가능 (복잡함)

구분하는 방법

방법 1: Xcode에서 Cmd+클릭

  @MainActor  // ← Cmd+클릭 시 정의로 이동
  final class ViewModel {}

  Attribute인 경우:
  // Swift 표준 라이브러리 정의로 이동
  @globalActor
  public actor MainActor : GlobalActor {
      public static let shared: MainActor
  }

  Property Wrapper인 경우:
  @propertyWrapper  // ← 이 키워드가 보임
  public struct Published<Value> {
      // ...
  }

  Macro인 경우:
  @attached(member)  // ← 이런 키워드들이 보임
  public macro Model() = #externalMacro(...)

방법 2: 적용 위치

  // 타입, 함수, 프로퍼티 모두 가능 → Attribute 또는 Macro
  @MainActor
  final class ViewModel {}

  @MainActor
  func updateUI() {}

  // 프로퍼티만 가능 → Property Wrapper
  @Published var count = 0  // ✅
  @Published final class User {}  // ❌ 컴파일 에러

  // 매개변수에도 가능 → Attribute
  func doSomething(@escaping completion: () -> Void) {}

  @MainActor의 정체

  @MainActorGlobal Actor Attribute입니다:

  // Swift Concurrency에서 제공
  @globalActor
  public actor MainActor: GlobalActor {
      public static let shared = MainActor()
  }

  // 사용
  @MainActor  // ← Attribute로 사용
  final class ViewModel {
      // 모든 메서드/프로퍼티가 MainActor에서 실행됨
  }

역할:

  • 컴파일러에게 "이 코드는 메인 스레드에서만 실행"을 알림

  • Actor isolation 보장

  • 런타임에 자동으로 메인 스레드로 전환

    프로젝트의 예시들 정리

  // ===== Attributes (컴파일러 제공) =====
  @MainActor
  @available(iOS 15, *)
  @objc
  @discardableResult
  @escaping
  @autoclosure

  // ===== Property Wrappers (사용자 정의 가능) =====
  @KeychainStored       // 프로젝트 정의
  @UserDefault          // 프로젝트 정의
  @Published            // Combine 제공
  @State                // SwiftUI 제공
  @StateObject          // SwiftUI 제공
  @ObservedObject       // SwiftUI 제공
  @Environment          // SwiftUI 제공

  // ===== Macros (Swift 5.9+) =====
  @Model                // SwiftData 제공
  @Attribute            // SwiftData 제공
  @Observable           // Swift 5.9+ 제공
  @Transient            // SwiftData 제공
profile
iOS Developer

0개의 댓글