Swift에서 @를 사용하는 3가지 종류:
컴파일러가 직접 제공하는 특수 어노테이션
@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)?
특징:
사용자가 정의할 수 있는 프로퍼티 접근 패턴
@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
특징:
Swift 5.9+에서 추가된 코드 생성 기능
@Model // ← Macro
final class UserEntity {}
@Attribute(.unique) // ← Macro
var id: String
@Observable // ← Macro (Swift 5.9+)
final class ViewModel {}
특징:
@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(...)
// 타입, 함수, 프로퍼티 모두 가능 → 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의 정체
@MainActor는 Global 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 제공