【问题标题】:Downcast set of type X that are subclass of of Y类型 X 的向下转换集,它们是 Y 的子类
【发布时间】:2018-05-31 00:08:31
【问题描述】:

注意:问题虽然有CoreData的例子,但和CoreData无关,只是一个例子

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

我们在mainViewController 中经常使用Notifications 来收听我们的NSManagedObjectContext 有新变化后的变化。

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

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

问题出在以下几点:
当添加新的Car 对象时,通知会触发,在mainViewController 中,我们需要检查它是否为Car 类型,如下所示:

if let insertedObjects = notification.userInfo?[NSInsertedObjectsKey] as? Set<Car> {
    print("we have some cars") // this will never execute
}

向下转换的Set&lt;Car&gt; 类型永远不会计算为真,因为Set 具有CarHuman 类型的元素。

我想要什么:
检查Set 是否具有CarHuman 类型的NSManagedObject 子类,因为我对其进行了向下转换。

我想做什么:
将其向下转换为NSManagedObject,并通过添加以下where 条件来检查Set 是否包含Car
insertedObjects.contains(Car),但它有一个编译时错误:

Cannot convert value of type '(Car).Type' to expected argument type 'NSManagedObject'

如果您有任何问题,请告诉我,而不仅仅是投反对票。

【问题讨论】:

    标签: ios swift downcast


    【解决方案1】:

    不确定类型转换(我想我记得是用同样的方法做的,虽然它是用数组做的),但是检查集合中是否有汽车是不同的:

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

    或更短(更简洁)的相同调用版本:

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

    【讨论】:

      【解决方案2】:

      首先将插入的对象向下转换为Set&lt;NSManagedObject&gt;。 要检查是否已插入任何汽车,请使用

      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
      

      改为。

      【讨论】:

        猜你喜欢
        • 2022-10-30
        • 1970-01-01
        • 2021-11-01
        • 2014-10-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-12
        • 1970-01-01
        相关资源
        最近更新 更多