Using reflection to set object properties without using setValue forKey

后端 未结 2 1345
悲&欢浪女
悲&欢浪女 2021-02-01 06:36

In Swift it\'s not possible use .setValue(..., forKey: ...)

  • nullable type fields like Int?
  • properties that have an enum
2条回答
  •  遇见更好的自我
    2021-02-01 07:00

    Unfortunately, this is impossible to do in Swift.

    KVC is an Objective-C thing. Pure Swift optionals (combination of Int and Optional) do not work with KVC. The best thing to do with Int? would be to replace with NSNumber? and KVC will work. This is because NSNumber is still an Objective-C class. This is a sad limitation of the type system.

    For your enums though, there is still hope. This will not, however, reduce the amount of coding that you would have to do, but it is much cleaner and at its best, mimics the KVC.

    1. Create a protocol called Settable

      protocol Settable {
         mutating func setValue(value:String)
      }
      
    2. Have your enum confirm to the protocol

      enum Types : Settable {
          case  FirstType, SecondType, ThirdType
          mutating func setValue(value: String) {
              if value == ".FirstType" {
                  self = .FirstType
              } else if value == ".SecondType" {
                  self = .SecondType
              } else if value == ".ThirdType" {
                  self = .ThirdType
              } else {
                  fatalError("The value \(value) is not settable to this enum")
              }
         }
      }
      
    3. Create a method: setEnumValue(value:value, forKey key:Any)

      setEnumValue(value:String forKey key:Any) {
          if key == "types" {
            self.types.setValue(value)
         } else {
            fatalError("No variable found with name \(key)")
         }
      }
      
    4. You can now call self.setEnumValue(".FirstType",forKey:"types")

提交回复
热议问题