Attributes
An attribute gives the compiler extra information about a declaration or a type.
You write an attribute with @ followed by its name, sometimes with
arguments in parentheses. Swift 6 has three places attributes appear:
declarations, types, and switch cases. This reference lists the common ones.
Writing attributes
An attribute precedes the thing it modifies. Some take arguments; many do not. Multiple attributes may stack.
@available(iOS 17, *)
@MainActor
final class ViewModel { ... }
Declaration attributes
Declaration attributes apply to constants, variables, functions, types, and members. The most frequently used:
| Attribute | Applies to | Effect |
|---|---|---|
@available | Any declaration | Marks platform/version availability or deprecation |
@main | Type | Designates the program's entry point |
@discardableResult | Function/method | Suppresses the unused-result warning |
@objc / @nonobjc | Declaration | Exposes (or hides) a declaration to Objective-C |
@objcMembers | Class | Implicitly applies @objc to members |
@MainActor | Declaration | Isolates the declaration to the main actor |
@Sendable | Function/closure | Marks it safe to pass across concurrency domains |
@resultBuilder | Type | Declares a result builder (e.g. for SwiftUI DSLs) |
@Observable | Class | Macro: makes a class observable for SwiftUI |
@propertyWrapper | Type | Declares a property wrapper |
@dynamicMemberLookup | Type | Enables dot access via a subscript |
@dynamicCallable | Type | Enables call syntax on instances |
@frozen | Enum/struct | Promises layout stability across versions (library evolution) |
@inlinable / @usableFromInline | Declaration | Exposes implementation for cross-module inlining |
@testable | Import | Grants test targets access to internal symbols |
@unchecked | Sendable conformance | Opts out of the compiler's Sendable checking |
@preconcurrency | Import/declaration | Eases interop with pre-concurrency code |
Note: several of these — including @Observable,
@main in many cases, and #Preview — are implemented as
Swift macros in modern Swift, even though they read like ordinary
attributes.
Type attributes
Type attributes appear in a type, most often on a function/closure type or a parameter's type.
| Attribute | Effect |
|---|---|
@escaping | Allows a closure parameter to outlive the function call |
@autoclosure | Wraps an argument expression in a closure automatically |
@Sendable | Marks a function type as safe to cross concurrency boundaries |
@convention(...) | Specifies calling convention (swift, block, c) |
func run(_ work: @escaping @Sendable () -> Void) { ... }
func assert(_ cond: @autoclosure () -> Bool) { ... }
Switch-case attributes
A small number of attributes apply to individual switch cases:
| Attribute | Effect |
|---|---|
@unknown | On default (or a case): warns if new enum cases appear, without breaking exhaustiveness |
switch status {
case .active: handleActive()
case .inactive: handleInactive()
@unknown default: handleFuture()
}
Tip: use @unknown default when switching over a
non-frozen enum from another module so future cases produce a warning rather than
silently falling into default.
Summary
Attributes are the compiler-facing annotations of Swift. Declaration attributes
cover availability, concurrency isolation, Objective-C interop, result builders,
and macros like @Observable; type attributes describe closure and
function behavior (@escaping, @autoclosure,
@Sendable); and @unknown future-proofs switch
statements over evolving enums.