Swift 3 - dynamic vs @objc
Asked Answered
R

3

55

What's the difference between marking a method as @objc vs dynamic, when would you do one vs the other?

Below is Apple's definition for dynamic.

dynamic Apply this modifier to any member of a class that can be represented by Objective-C. When you mark a member declaration with the dynamic modifier, access to that member is always dynamically dispatched using the Objective-C runtime. Access to that member is never inlined or devirtualized by the compiler.

Because declarations marked with the dynamic modifier are dispatched using the Objective-C runtime, they’re implicitly marked with the objc attribute.

Rakehell answered 24/11, 2016 at 23:40 Comment(1)
Has your question been answered?Ultima
A
95

A function/variable declared as @objc is accessible from Objective-C, but Swift will continue to access it directly via static or virtual dispatch. This means if the function/variable is swizzled via the Objective-C framework, like what happens when using Key-Value Observing or the various Objective-C APIs to modify classes, calling the method from Swift and Objective-C will produce different results.

Using dynamic tells Swift to always refer to Objective-C dynamic dispatch. This is required for things like Key-Value Observing to work correctly. When the Swift function is called, it refers to the Objective-C runtime to dynamically dispatch the call.

Arsenal answered 25/11, 2016 at 2:38 Comment(4)
I didn't know KVO is being swizzled, can you elaborate on this point?Rakehell
@Rakehell KVO creates a dynamic subclass, replacing your property with one that is wrapped in willChangeValueForKey/didChangeValueForKey calls, unless automaticallyNotifiesObserversForKey is used to opt-out.Arsenal
Just for clarification, if I make sure I only use Swift4 with no interoperability with objC, I can completely ignore @dynamic (and @objc)?Bortz
@Bortz Yes, as of Swift 4 these attributes only change how your code interacts with Objective-C.Arsenal
U
17

As that quote says, dynamic implies @objc.

Unless you specify a class as being dynamic, the compiler is free to optimize away and inline its methods. This brings huge performance benefits, but it means that you can't change those method implementations at run time. If you're planning to mess around with those methods at runtime using the reflection capabilities of the Objective C runtime, you'll need to use dynamic. You'll incur a performance penalty (your code will run at Objective C levels of speed, rather than near C-like levels), but you'll gain that extra dynamism.

Ultima answered 24/11, 2016 at 23:46 Comment(0)
T
9

Swift @objc and dynamic

[Objective C Runtime]

Swift uses next reserved words for working with Objective-C:

  • @objc[About] - Compile time - To expose Swift's api for Objective-C runtime.

    1. opening Swift public functionality for Objective-C consumers
    2. using #selector[About] in a Swift code
  • dynamic - Run time - to enable a message dispatch[About](Objective-C's world) for NSObject object, which is different than in Swift's world: class uses table dispatch (virtual dispatch) and struct Protocol Witness Table PWT

    It is used for:

    1. [KVO]
    2. class extensions to have a possibility to override an extension function
    3. swizzling[Example]

Pre Swift v4 dynamic included @objc

Terrill answered 30/3, 2020 at 19:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.