23

Could you briefly explain what @objc and dynamic mean in Swift 4 using Xcode 9.x?

With tries and errors and following articles in the stackoverflow, I have eventually achieved this snippet to work. But I would like to know a little bit about those magical keywords.

enter image description here

class SampleViewController: NSViewController {

  @objc class Parameters : NSObject {
    @objc dynamic var value1: Double = 0  // bound to Value of a NSTextfield with NumberFormatter
    @objc dynamic var value2: Double = 0  // as "parameters.value1" for the Model Key Path
  }

  @objc dynamic var parameters = Parameters()

  @objc dynamic var value3: Double {  // in the similar way as "value3" for the Model Key Path
    get {
      return parameters.value1 + parameters.value2
    }
  }

  override class func keyPathsForValuesAffectingValue(forKey key: String) -> Set<String> {
    switch key {
    case "value3" :
      return Set(["parameters.value1", "parameters.value2"])
    default:
      return super.keyPathsForValuesAffectingValue(forKey: key)
    }
  }

}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
Tora
  • 970
  • 1
  • 8
  • 15
  • 5
    `@objc` exposes the variable to the ObjC runtime. `dynamic` tells the runtime to use dynamic dispatch instead of the default static dispatch. `dynamic` also implies `@objc` so `@objc dynamic` is redundant. You mostly utilize them in KVO and Cocoa Binding. See this article: https://krakendev.io/blog/hipster-swift#dynamic – Mike Henderson Feb 01 '18 at 13:33

3 Answers3

16

@objc means you want your Swift code (class, method, property, etc.) to be visible from Objective-C.

dynamic means you want to use Objective-C dynamic dispatch.

Swift 3 - dynamic vs @objc

Gagandeep Gambhir
  • 4,225
  • 1
  • 29
  • 34
  • Dynamic dispatch makes sense for methods (func's) but what does that mean for var's? You don't "call/dispatch" vars right? – wcochran Nov 14 '20 at 00:03
15

Having fun with Xcode and its disassembler, I have found some. Thanks to Mike Henderson's comment.

Firstly, adding a @objc modifier seems to have the compiler write its corresponding symbol name in a __OBJC segment of executables and/or library files, which will be then used by the Objective-C run-time system. otool -o filename command shows us the contents of __OBJC segment.

Secondly, adding a dynamic modifier seems to have the compiler insert additional assembler codes to interact with the Objective-C run-time system. The additional code realizes that accessing dynamic properties will be done through objc_msgSend() and its related functions. Similarly, calling dynamic methods also will be done through objc_msgSend().

Now, in my understandings, the jargon dynamic dispatch implies use of objc_msgSend() while static dispatch does no use of it. In the latter case, both accessing variables and calling functions will be done without intervention of the Objective-C run-time system, which is in the similar, but not exactly same, way of C++ ABI.

Apparently, static one is faster than dynamic one. But static one is incapable of Objective-C's magical benefits, though. With the programming language Swift, we have opportunities to utilize both aspects by choosing either static or dynamic dispatch depending on the situation, by omitting or adding those magical keywords, respectively.

Thanks!

Further readings:

Tora
  • 970
  • 1
  • 8
  • 15
1

According to Apple Doc, there is a specific use case for @obc dynamic vars.

Mark properties that you want to observe through key-value observing (KVO) with both the @objc attribute and the dynamic modifier.

https://developer.apple.com/documentation/swift/using-key-value-observing-in-swift

kikeenrique
  • 2,589
  • 2
  • 25
  • 46