作为 Y 的子类的类型 X 的向下转换集
Downcast set of type X that are subclass of of Y
注:虽然题中有CoreData
例题,但与CoreData
无关,只是例题
我们正在开发一个 Swift 项目,其中 CoreData
作为缓存层。
我们在 mainViewController
中大量使用 Notification
来收听 NSManagedObjectContext
有新变化后的变化。
在我们添加具有以下层次结构的新实体之前,这一直很有效:
- 实体
Vehicle
是一个具有某些属性的基础 class。
- 实体
Car
是 Vehicle
的子class,具有特定属性和与 Human
实体的 toMany 关系。
- 实体
Human
是一个具有特定属性的基础class,它与Car
. 有关系
问题如下:
当添加新的 Car
对象时,通知会触发,在 mainViewController
中,我们需要检查它是否属于 Car
类型,如下所示:
if let insertedObjects = notification.userInfo?[NSInsertedObjectsKey] as? Set<Car> {
print("we have some cars") // this will never execute
}
类型向下转换 Set<Car>
永远不会计算为真,因为 Set
具有类型 Car
和 Human
的元素。
我想要的:
检查 Set
是否具有 Car
或 Human
类型的 NSManagedObject subclass,因为我向下转换它。
我尝试做的事情:
向下转换为 NSManagedObject
,并通过添加以下 where
条件检查 Set
是否包含 Car
:
insertedObjects.contains(Car)
,但它有一个编译时错误:
Cannot convert value of type '(Car).Type' to expected argument type 'NSManagedObject'
如果您有任何问题,请告诉我,而不仅仅是投反对票。
不确定类型转换(我想我记得是用同样的方法做的,而且它起作用了,尽管它是用数组),但是检查集合中是否有汽车是不同的:
set.contains { (element) -> Bool in
return element is Car
}
或同一调用的更短(更简洁)版本:
set.contains(where: { [=11=] is Car })
首先将插入的对象向下转换为Set<NSManagedObject>
。
要检查是否插入了任何汽车,请使用
if let insertedObjects = notification.userInfo?[NSInsertedObjectsKey] as? Set<NSManagedObject> {
if insertedObjects.contains(where: { [=10=] is Car }) {
print("we have some cars")
}
}
要将插入的汽车对象作为(可能为空的)数组获取,
使用 flatMap()
:
if let insertedObjects = notification.userInfo?[NSInsertedObjectsKey] as? Set<NSManagedObject> {
let insertedCars = insertedObjects.flatMap { [=11=] as? Car }
}
你的方法
if insertedObjects.contains(Car)
无法编译,因为
func contains(_ member: Set.Element) -> Bool
期望元素类型的 实例 作为参数。
如上所示,您可以使用基于谓词的变体
func contains(where predicate: (Element) throws -> Bool) rethrows -> Bool
相反。
注:虽然题中有CoreData
例题,但与CoreData
无关,只是例题
我们正在开发一个 Swift 项目,其中 CoreData
作为缓存层。
我们在 mainViewController
中大量使用 Notification
来收听 NSManagedObjectContext
有新变化后的变化。
在我们添加具有以下层次结构的新实体之前,这一直很有效:
- 实体
Vehicle
是一个具有某些属性的基础 class。 - 实体
Car
是Vehicle
的子class,具有特定属性和与Human
实体的 toMany 关系。 - 实体
Human
是一个具有特定属性的基础class,它与Car
. 有关系
问题如下:
当添加新的 Car
对象时,通知会触发,在 mainViewController
中,我们需要检查它是否属于 Car
类型,如下所示:
if let insertedObjects = notification.userInfo?[NSInsertedObjectsKey] as? Set<Car> {
print("we have some cars") // this will never execute
}
类型向下转换 Set<Car>
永远不会计算为真,因为 Set
具有类型 Car
和 Human
的元素。
我想要的:
检查 Set
是否具有 Car
或 Human
类型的 NSManagedObject subclass,因为我向下转换它。
我尝试做的事情:
向下转换为 NSManagedObject
,并通过添加以下 where
条件检查 Set
是否包含 Car
:
insertedObjects.contains(Car)
,但它有一个编译时错误:
Cannot convert value of type '(Car).Type' to expected argument type 'NSManagedObject'
如果您有任何问题,请告诉我,而不仅仅是投反对票。
不确定类型转换(我想我记得是用同样的方法做的,而且它起作用了,尽管它是用数组),但是检查集合中是否有汽车是不同的:
set.contains { (element) -> Bool in
return element is Car
}
或同一调用的更短(更简洁)版本:
set.contains(where: { [=11=] is Car })
首先将插入的对象向下转换为Set<NSManagedObject>
。
要检查是否插入了任何汽车,请使用
if let insertedObjects = notification.userInfo?[NSInsertedObjectsKey] as? Set<NSManagedObject> {
if insertedObjects.contains(where: { [=10=] is Car }) {
print("we have some cars")
}
}
要将插入的汽车对象作为(可能为空的)数组获取,
使用 flatMap()
:
if let insertedObjects = notification.userInfo?[NSInsertedObjectsKey] as? Set<NSManagedObject> {
let insertedCars = insertedObjects.flatMap { [=11=] as? Car }
}
你的方法
if insertedObjects.contains(Car)
无法编译,因为
func contains(_ member: Set.Element) -> Bool
期望元素类型的 实例 作为参数。 如上所示,您可以使用基于谓词的变体
func contains(where predicate: (Element) throws -> Bool) rethrows -> Bool
相反。