SwiftQA Random

How does Swift bridge with Objective-C?

The foundation: two different runtimes talking to each other

Objective-C uses dynamic message dispatch (objc_msgSend); Swift uses static/witness-table dispatch. Bridging translates between these models at compile time and, in some cases, at runtime.

1. The bridging header — importing Objective-C into Swift

A bridging header (MyApp-Bridging-Header.h) lists Objective-C headers you want visible to Swift.

2. The generated interface — the reverse direction

A Swift framework generates a -Swift.h header with Objective-C-compatible declarations for anything marked @objc. Pure Swift structs, generics, enums with associated values generally cannot bridge.

Swift constructBridges to ObjC?
class subclassing NSObject, @objc methodsYes
struct/enumNo
Enum with associated valuesNo
Generic class/functionNo
Protocol without associated types, @objcYes
ClosuresYes, bridged to blocks

3. Automatic type bridging

Swift typeObjective-C type
StringNSString
ArrayNSArray
DictionaryNSDictionary
Int, Double, BoolNSNumber

Implemented via _ObjectiveCBridgeable. This bridging isn’t always free — Array/Dictionary bridging can be lazy/no-op when storage is compatible, but bridging a [CustomStruct] forces element-by-element conversion.

4. Memory management reconciliation

Both use ARC, but naming conventions (init, copy, new, alloc) still matter for correct retain/release insertion at the boundary.

5. Nullability and Optionals

nullable/nonnull annotations tell the Swift importer whether to expose T, T?, or T!. Un-annotated legacy headers are why implicitly-unwrapped optionals still show up at interop boundaries.

6. dynamic and message dispatch

Features like KVO/swizzling need dynamic, forcing objc_msgSend-style dispatch.

7. Selectors and #selector

button.addTarget(self, action: #selector(handleTap), for: .touchUpInside)

Compile-time checked, closing off typo’d-selector-string footguns.

One-liner if pressed: “Swift bridges to Objective-C through compiler-generated headers in both directions, automatic value-type conversion via a compiler-known bridging protocol, and the @objc/dynamic attributes that opt Swift declarations into Objective-C’s message-dispatch model — with nullability annotations closing the gap between ObjC’s unchecked pointers and Swift’s Optionals.”