类型为X的Downcast集,它是Y

时间:2017-12-17 12:24:45

标签: ios swift downcast

注意 :虽然问题有一个CoreData示例,但它与CoreData无关,它&# 39;只是一个例子

我们正在开发一个以CoreData作为缓存层的Swift项目。

我们Notification中的mainViewController经常使用NSManagedObjectContext来听取Vehicle发生新变化后的更改。

在我们添加具有以下层次结构的新实体之前,这很有效:

  • 实体Car是具有一些属性的基类。
  • 实体VehicleHuman的子类,具有特定属性和与Human实体的toMany关系。
  • 实体Car是具有特定属性的基类,它与Car具有关系。

Entities

问题如下:
当添加新的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永远不会评估为true。

我想要的是什么:
检查Car是否具有类型HumanNSManagedObject的NSManagedObject子类,因为我向下转发它。

我尝试做的事情:
向下转贴到Set,并通过添加以下Car条件检查where是否包含insertedObjects.contains(Car)
Cannot convert value of type '(Car).Type' to expected argument type 'NSManagedObject' ,但它有编译时错误:

var mouseRotationData = {
    startX : 0,
    startY : 0,
    endX : 0,
    endY : 0,
    x : 0,
    y : 0
};

如果您有任何疑问,请告诉我,而不仅仅是低估。

2 个答案:

答案 0 :(得分:1)

不确定类型转换(我想我记得以同样的方式做它并且它工作,虽然它是一个数组),但检查集合中是否有汽车是不同的:

set.contains { (element) -> Bool in
    return element is Car
}

或同一通话的更短(更简洁)版本:

set.contains(where: { $0 is Car })

答案 1 :(得分:0)

首先将插入的对象向下转发到Set<NSManagedObject>。 要检查是否插入了任何车辆,请使用

if let insertedObjects = notification.userInfo?[NSInsertedObjectsKey] as? Set<NSManagedObject> {

    if insertedObjects.contains(where: { $0 is Car }) {
        print("we have some cars")
    }

}

要将插入的汽车对象作为(可能为空)数组, 使用flatMap()

if let insertedObjects = notification.userInfo?[NSInsertedObjectsKey] as? Set<NSManagedObject> {

    let insertedCars = insertedObjects.flatMap { $0 as? Car }

}

你的方法

if insertedObjects.contains(Car)

因为

而无法编译
func contains(_ member: Set.Element) -> Bool

期望元素类型的实例作为参数。 如上所示,您可以使用基于谓词的变体

func contains(where predicate: (Element) throws -> Bool) rethrows -> Bool

代替。