有没有办法使用 value(forKeyPath:) 访问 KVC 中的数组元素?
Is there a way to access an array element in KVC using value(forKeyPath:)?
假设我有一些符合 KVC 的 objects 类似于以下内容:
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 也是可能的,不需要 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"
这里澄清一下:不需要把NSObjectclass改成struct。即使是 class 也可以。我把这算作一个答案。
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]
假设我有一些符合 KVC 的 objects 类似于以下内容:
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 也是可能的,不需要 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"
这里澄清一下:不需要把NSObjectclass改成struct。即使是 class 也可以。我把这算作一个答案。
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]