swift - KVC的优势
问题描述
我一直试图弄清楚这一点,但无法理解 KVC 的优势,除了:
- 编译器检查(从而避免字符串类型的代码)
- 与 KVO 一起使用
我不确定除了上面提到的 2 个案例(我知道我可能错了)之外,使用 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" */
我的意思是我为什么要使用:
让 firstNameKey = \Profile.firstName
profile1[keyPath: firstNameKey] /* 返回字符串 "John" */
代替 :
profile1.firstName // 返回字符串“John”
如果有人有一些代码示例/示例,那么如果他们可以使用 swift 进行解释,那就太好了(因为我的 Objective-C 不好)
解决方案
您使用的示例不是使用KVC或keyPath本身的最佳情况。
当您使用协议时, keyPath的真正力量 IMO会被释放出来。让我给你举个例子 -
假设您有一个Identifiable
只有一个成员的协议 - id
. 符合此的每种类型都必须使用id
唯一标识它的属性。
protocol Identifiable {
var id: Int { get }
}
struct Person: Identifiable {
var id: Int
var name: String
}
在这里,Person
有成员的类型id
听起来不太好。考虑另一个 -
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
替代品。
推荐阅读
- c# - Ef Core 外键是唯一的,这不是我想要的
- postgresql - 如何查看用户在 PostgreSQL 中执行的查询?
- excel - 文本框日期(今天)“DD/MM/YYYY”在输入单元格“DD/MM/YYYY”时发生变化
- flutter - 将“MainAxisSize”设置为父小部件的最小值
- kotlin - 如何有效地检查 Kotlin 集合中的关键字?
- token - 如何在 Datastage 的分层阶段使用时间到期承载令牌?
- android - Android MediaPlayer addTimedTextSource 在标题“结束”时不通知,仅在标题“开始”时通知
- java - Java - 在列表中多次添加值
- java - java编译器如何允许一个类有自己的类型引用?
- python - Python字典更改一个值(列表)会更改所有值(列表),深度复制无法解决问题