Skip to main content
The @objc attribute is a compiler directive that exposes Swift declarations to the Objective-C runtime and allows Objective-C code to interact with Swift APIs. Applying this attribute instructs the Swift compiler to generate the necessary Objective-C metadata and message-passing thunks for the annotated entity.

Syntax and Symbol Renaming

By default, the Swift compiler infers the Objective-C symbol name from the Swift declaration. You can explicitly provide an Objective-C name by passing an identifier to the attribute. This is required when the Swift name is invalid in Objective-C or when conforming to a specific Objective-C naming convention.

Applicability and Type Compatibility

The @objc attribute can be applied to classes, protocols, methods, properties, initializers, subscripts, enumerations, and extensions. Applying @objc to an extension is a common pattern that implicitly exposes all eligible members within that block to Objective-C without requiring individual annotations. The Swift compiler enforces strict type compatibility rules. Every type in the annotated declaration’s signature (parameters, return types, and property types) must be representable in Objective-C. Compatible Types:
  • Objective-C classes (NSObject and its subclasses).
  • Swift classes inheriting from an Objective-C class.
  • @objc protocols.
  • Bridged Swift standard library types (e.g., Int, Double, String, Array, Dictionary).
  • Swift enumerations with an integer raw type (e.g., Int, Int8, UInt16, Int32).
Incompatible Types:
  • Swift structures (struct).
  • Tuples.
  • Generic types or methods.
  • Swift enumerations with associated values or non-integer raw types.
  • Swift-only protocols.

Implicit @objc Inference

In certain contexts, the Swift compiler implicitly applies the @objc attribute to declarations, meaning explicit annotation is not required:
  1. Overriding a method or property from an Objective-C superclass.
  2. Implementing a requirement from an @objc protocol.
  3. Declarations marked with specific Interface Builder or Core Data attributes (@IBAction, @IBOutlet, @IBInspectable, @NSManaged).

The @objcMembers Attribute

To avoid annotating individual members of a class, the @objcMembers attribute can be applied to the class declaration. This implicitly applies the @objc attribute to all eligible members of the class, its extensions, and its subclasses.

@objc vs. dynamic Dispatch

The @objc attribute dictates visibility to the Objective-C runtime, but it does not strictly dictate the dispatch mechanism. By default, Swift uses static or vtable dispatch for performance, even for @objc methods, when called from Swift code. To force a declaration to use dynamic dispatch via Objective-C message passing (objc_msgSend), it must be marked with both @objc and the dynamic modifier. However, the dynamic modifier is independent of @objc. You can apply dynamic to Swift structures or non-Objective-C classes to enable Swift’s native dynamic dispatch (often used with @_dynamicReplacement). The @objc attribute is only required alongside dynamic when the dynamic dispatch must specifically route through the Objective-C runtime.
Tired of Poor Swift Skills? Fix That With Deep Grasping!Learn More