【问题标题】:Is there a way to access an array element in KVC using value(forKeyPath:)?有没有办法使用 value(forKeyPath:) 访问 KVC 中的数组元素?
【发布时间】:2018-10-10 21:29:37
【问题描述】:

假设我有一些类似于以下的符合 KVC 的对象:

class Person : NSObject {
   var office: Office
   var firstName: String
   var lastName: String
   var reports: [Report]

   init( office: Office, 
         firstName: String,
         lastName: String,
         reports: [Report] ) {

      ...

   }
}

class Office : NSObject {
   var building: String
   var room: Int

   init( building: String, 
         room: Int ) {

      ...

   }

}

class Report : NSObject {
   var title: String
   var contents: String 

   init( title: String, 
         contents: String ) {

      ...

   }
}

我创建了一个实例,人

let person = Person(
                office: Office( 
                    building: "Main",
                    room: 2 ),
                firstName: "Bob",
                lastName: "Roberts",
                reports: [
                    Report( title: "Today's weather", contents: "..." ),
                    Report( title: "Traffic", contents: "..." ),
                    Report( title: "Stocks", contents: "..." )
                ] )

我可以使用 person.value(forKeyPath:) 来访问 person 的属性和嵌套属性,如下所示:

person.value(forKeyPath: "firstName") // "Bob"
person.value(forKeyPath: "office.room" ) // 2

但是,KVC 中有没有办法从第二个报告中获取标题?

类似

person.value(forKeyPath: "reports[1].title" ) // "Traffic"

【问题讨论】:

    标签: swift kvc


    【解决方案1】:

    Swift 的原生 KVC 甚至可以使用结构体,不需要 ObjC 运行时

    struct Person {
        var office: Office
        var firstName: String
        var lastName: String
        var reports: [Report]
    }
    
    struct Office {
        var building: String
        var room: Int
    }
    
    struct Report {
        var title: String
        var contents: String
    }
    
    let person = Person(office: Office(building: "Main", room: 2 ),
                        firstName: "Bob", lastName: "Roberts",
                        reports: [
                            Report( title: "Today's weather", contents: "..." ),
                            Report( title: "Traffic", contents: "..." ),
                            Report( title: "Stocks", contents: "..." )
        ])
    
    
    let keyPath = \Person.reports[1].title
    let title = person[keyPath: keyPath] // "Traffic"
    

    【讨论】:

      【解决方案2】:

      这里澄清一下:您不需要将 NSObject 类更改为 struct。甚至一堂课也可以工作。我认为这是一个答案。

      class Person : NSObject {
          var office: Office!
          @objc var firstName: String!
          var lastName: String!
          @objc var reports: [Report]!
      
          init( office: Office,
                firstName: String,
                lastName: String,
                reports: [Report] ) {
              super.init()
              self.office = office
              self.firstName = firstName
              self.lastName = lastName
              self.reports = reports
          }
      }
      
      class Office : NSObject {
          var building: String!
          var room: Int!
      
          init( building: String,
                room: Int ) {
              self.building = building
              self.room = room
          }
      }
      
      class Report : NSObject {
          var title: String!
          var contents: String!
      
          init( title: String,
                contents: String ) {
              self.title =  title
              self.contents = contents
          }
      }
      
      let person = Person(
          office: Office(
              building: "Main",
              room: 2 ),
          firstName: "Bob",
          lastName: "Roberts",
          reports: [
              Report( title: "Today's weather", contents: "..." ),
              Report( title: "Traffic", contents: "..." ),
              Report( title: "Stocks", contents: "..." )
          ] )
      
      
      person[keyPath: \Person.reports[1].title]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-02-04
        • 1970-01-01
        • 1970-01-01
        • 2022-08-12
        • 1970-01-01
        • 2022-07-06
        • 2020-09-15
        • 1970-01-01
        相关资源
        最近更新 更多