6

Objective-C has a setValue method which allows the developer to set a specific value to a field by it's name.

How can I do that in Swift without inheriting from NSObject and actually use the setValue method?

nhgrif
  • 61,578
  • 25
  • 134
  • 173
YogevSitton
  • 10,068
  • 11
  • 62
  • 95
  • 2
    Have you looked at http://stackoverflow.com/questions/24092285/is-key-value-observation-kvo-available-in-swift ? – Grimxn Sep 21 '15 at 13:03

1 Answers1

2

You can use KVC to do so, afaik. Have a look at this cool example: https://www.raywenderlich.com/163857/whats-new-swift-4

struct Lightsaber {
  enum Color {
    case blue, green, red
  }
  let color: Color
}

class ForceUser {
  var name: String
  var lightsaber: Lightsaber
  var master: ForceUser?

  init(name: String, lightsaber: Lightsaber, master: ForceUser? = nil) {
    self.name = name
    self.lightsaber = lightsaber
    self.master = master
  }
}

let sidious = ForceUser(name: "Darth Sidious", lightsaber: Lightsaber(color: .red))
let obiwan = ForceUser(name: "Obi-Wan Kenobi", lightsaber: Lightsaber(color: .blue))
let anakin = ForceUser(name: "Anakin Skywalker", lightsaber: Lightsaber(color: .blue), master: obiwan)

// Use keypath directly inline and to drill down to sub objects
let anakinSaberColor = anakin[keyPath: \ForceUser.lightsaber.color]  // blue

// Access a property on the object returned by key path
let masterKeyPath = \ForceUser.master
let anakinMasterName = anakin[keyPath: masterKeyPath]?.name  // "Obi-Wan Kenobi"

// AND HERE's YOUR ANSWER
// Change Anakin to the dark side using key path as a setter
anakin[keyPath: masterKeyPath] = sidious
anakin.master?.name // Darth Sidious
inigo333
  • 3,088
  • 1
  • 36
  • 41