Есть ли способ получить доступ к элементу массива в KVC, используя значение (forKeyPath :)? - PullRequest
0 голосов
/ 11 октября 2018

Предположим, у меня есть некоторые объекты, совместимые с 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 ) {

      ...

   }
}

И я создаю экземпляр person

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.value(forKeyPath: "firstName") // "Bob"
person.value(forKeyPath: "office.room" ) // 2

Однако есть ли в KVC способ для заголовка из второго отчета?

Что-токак

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

Ответы [ 2 ]

0 голосов
/ 11 октября 2018

Вот пояснение: вам не нужно менять класс 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]
0 голосов
/ 11 октября 2018

Это возможно с собственным KVC Swift даже со структурами, среда выполнения 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"
...