When to use objc in Swift?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Swift is a powerful and modern programming language designed for iOS, macOS, watchOS, and tvOS. While Swift is both powerful and expressive, there are moments when you need to interact with Objective-C, the predecessor to Swift for Apple’s platforms. Understanding when and how to use `@objc` in Swift is critical, especially for interoperability with Objective-C codebases.
The Purpose of `@objc`
The `@objc` attribute can be used to indicate that a Swift declaration can be accessed from Objective-C code. This is essential for using Swift within mixed-language apps or legacy projects that still include significant amounts of Objective-C code.
When to Use `@objc`
Here are some situations where using `@objc` in Swift is appropriate:
- Interacting with Objective-C APIs:
- If you want to use Cocoa APIs that are entirely written in Objective-C or expose Swift methods to Objective-C, you'll need to use `@objc`.
- Target-Action Design Pattern:
- When configuring actions for user interface controls (like a UIButton) at runtime, methods need `@objc` as they're stored in an Objective-C runtime's table.
- Example:
- The `@objc` modifier is required when using dynamic dispatch or reflection, as Swift doesn’t have built-in support for these features without the Objective-C runtime.
- Example of `@objc` with `@objcMembers`:
- Properties that need to be observed using KVO should be marked with `@objc` or explicitly declared with the `dynamic` modifier.
- When an Objective-C class must call a Swift delegate or a delegate method, these methods should be marked with `@objc`.
- @objcMembers: If several members of a class need to be exposed to Objective-C, you can mark the class with `@objcMembers` rather than adding `@objc` to every method.
- dynamic: Tells the Swift runtime to use dynamic dispatch. Normally, Swift uses static dispatch for performance but using `@objc` permits method overriding at runtime due to Objective-C's dynamic nature.
- optional: For protocol methods intended to be optional, mark the protocol as `@objc`.
- Dynamic dispatch introduces subtle overhead due to runtime lookups.
- Classes utilizing `@objc` directly or through directives like `@objcMembers` must derive from `NSObject`.
- Cannot expose Swift-specific features like generics directly to Objective-C.

