KVC的优势
Advantages of KVC
我已经尝试解决这个问题一段时间了,但除了 :
之外无法理解 KVC 的优势
- 编译器检查(从而避免字符串类型的代码)
- 与 KVO 一起使用
除了上述两种情况(我知道我可能错了),我不确定使用 KVC 是否有任何优势,但我找不到!
喜欢考虑以下代码:
class Profile: NSObject {
@objc var firstName: String
var lastName: String
init(firstName: String,lastName: String) {
self.firstName = firstName
self.lastName = lastName
super.init()
}
}
let profile1 = Profile(firstName: "John", lastName: "Doe")
profile1.firstName // returns String "John"
profile1.value(forKey: "firstName") // returns Optional<Any>
let firstNameKey = \Profile.firstName
profile1[keyPath: firstNameKey] /* returns String "John" */
我的意思是我为什么要使用:
let firstNameKey = \Profile.firstName
profile1[keyPath: firstNameKey]
/* returns String "John" */
而不是:
profile1.firstName // returns String "John"
如果有人有一些代码 sample/examples,那么如果他们可以使用 swift 来解释它,那就太好了(因为我的 Objective-C 不好)
您使用的示例不是使用 KVC 或 keyPath 本身的最佳情况。
当您使用 protocols 时,keyPath 的真正力量 IMO 会释放出来。让我举个例子-
假设您有一个协议 Identifiable
,它只有一个成员 - id
。符合此要求的每种类型都必须使用 id
属性 来唯一标识它。
protocol Identifiable {
var id: Int { get }
}
struct Person: Identifiable {
var id: Int
var name: String
}
在这里,具有成员 id
的 Person
类型听起来不太好。考虑另一个 -
struct Book: Identifiable {
var id: Int
var title: String
var author: String
}
在这里,一本书也可以通过 id
唯一标识,但听起来不太好。
这就是 keyPath 发挥作用的地方。
您可以在协议内部定义成员,并使用某个名称让符合类型为该特定协议成员编写自己的名称。符合类型可以映射或告诉编译器它们的特定成员是使用 keyPath.
协议内部成员的替换
protocol Identifiable {
associatedtype ID
static var id: WritableKeyPath<Self,ID> { get }
}
struct Person: Identifiable {
static var id = \Person.socialSecurityNumber
var socialSecurityNumber: Int
var name: String
}
struct Book: Identifiable {
static var id = \Book.isbn
var isbn: String
var title: String
var author: String
}
func printID<T: Identifiable>(aType: T) {
print(aType[keyPath: T.id])
}
printID(aType: Person(socialSecurityNumber: 1234, name: "Shubham Bakshi"))
printID(aType: Book(isbn: "qwertyui", title: "The Theory of Everything", author: "Stephen W. Hawking"))
作为一个额外的优势,您的符合类型可以具有任何类型的 id
、String
、Int
而不是仅 Int
(如前例所示)
如果你只想给id
一个特定的类型,只说Int
,你可以用这个替换我们协议的定义 -
protocol Identifiable {
static var id: WritableKeyPath<Self,Int> { get }
}
这将强制符合类型使用 Int
作为它们的 id
替代品。
我已经尝试解决这个问题一段时间了,但除了 :
之外无法理解 KVC 的优势- 编译器检查(从而避免字符串类型的代码)
- 与 KVO 一起使用
除了上述两种情况(我知道我可能错了),我不确定使用 KVC 是否有任何优势,但我找不到!
喜欢考虑以下代码:
class Profile: NSObject {
@objc var firstName: String
var lastName: String
init(firstName: String,lastName: String) {
self.firstName = firstName
self.lastName = lastName
super.init()
}
}
let profile1 = Profile(firstName: "John", lastName: "Doe")
profile1.firstName // returns String "John"
profile1.value(forKey: "firstName") // returns Optional<Any>
let firstNameKey = \Profile.firstName
profile1[keyPath: firstNameKey] /* returns String "John" */
我的意思是我为什么要使用:
let firstNameKey = \Profile.firstName
profile1[keyPath: firstNameKey] /* returns String "John" */
而不是:
profile1.firstName // returns String "John"
如果有人有一些代码 sample/examples,那么如果他们可以使用 swift 来解释它,那就太好了(因为我的 Objective-C 不好)
您使用的示例不是使用 KVC 或 keyPath 本身的最佳情况。
当您使用 protocols 时,keyPath 的真正力量 IMO 会释放出来。让我举个例子-
假设您有一个协议 Identifiable
,它只有一个成员 - id
。符合此要求的每种类型都必须使用 id
属性 来唯一标识它。
protocol Identifiable {
var id: Int { get }
}
struct Person: Identifiable {
var id: Int
var name: String
}
在这里,具有成员 id
的 Person
类型听起来不太好。考虑另一个 -
struct Book: Identifiable {
var id: Int
var title: String
var author: String
}
在这里,一本书也可以通过 id
唯一标识,但听起来不太好。
这就是 keyPath 发挥作用的地方。
您可以在协议内部定义成员,并使用某个名称让符合类型为该特定协议成员编写自己的名称。符合类型可以映射或告诉编译器它们的特定成员是使用 keyPath.
协议内部成员的替换protocol Identifiable {
associatedtype ID
static var id: WritableKeyPath<Self,ID> { get }
}
struct Person: Identifiable {
static var id = \Person.socialSecurityNumber
var socialSecurityNumber: Int
var name: String
}
struct Book: Identifiable {
static var id = \Book.isbn
var isbn: String
var title: String
var author: String
}
func printID<T: Identifiable>(aType: T) {
print(aType[keyPath: T.id])
}
printID(aType: Person(socialSecurityNumber: 1234, name: "Shubham Bakshi"))
printID(aType: Book(isbn: "qwertyui", title: "The Theory of Everything", author: "Stephen W. Hawking"))
作为一个额外的优势,您的符合类型可以具有任何类型的 id
、String
、Int
而不是仅 Int
(如前例所示)
如果你只想给id
一个特定的类型,只说Int
,你可以用这个替换我们协议的定义 -
protocol Identifiable {
static var id: WritableKeyPath<Self,Int> { get }
}
这将强制符合类型使用 Int
作为它们的 id
替代品。