NSArray元素无法匹配Swift数组元素类型

问题描述:

我有一个核心数据对象(Order),它有一个返回另一个Core Data对象(OrderWaypoint)数组的方法。NSArray元素无法匹配Swift数组元素类型

func getOrderedWaypoints() -> [OrderWaypoint] { 
    let nameDescriptor = NSSortDescriptor(key: "stop_number", ascending: true) 
    let sorted: [OrderWaypoint] = self.waypoints.sortedArrayUsingDescriptors([nameDescriptor]) as [OrderWaypoint] 
    return sorted 
} 

一切正常,使用下面的循环

for waypoint in order.getOrderedWaypoints() { 
    // do something 
} 

当主目标如期但是,当我试图在我的测试目标完全一样的事情

fatal error: NSArray element failed to match the Swift Array Element type

我试着铸造的价值,但似乎无法得到它的工作。任何想法为什么它在主要目标而不是测试目标中起作用?

编辑

嗯打破它进一步下降,这个问题特别是当我试图让一个项目从数组中发生的事情。

var orderedList: [OrderWaypoint] = order.getOrderedWaypoints() 

for var i = 0; i < orderedList.count; i++ { 
    var waypoint = orderedList[i] 
    // do something 
} 
+0

创建NSArray并将其传递给Swift代码的代码在哪里? – Mark 2014-09-19 18:15:01

+0

我用方法定义更新了原始文章。 order.waypoints是核心数据中的NSSet。我应用排序描述符来获取NSArray并向下转换为[OrderWaypoint]。 – 2014-09-19 18:19:18

+2

你有没有得到这个工作?我遇到了类似的情况 - 使用核心数据的子类应该可以工作,但是我们遇到了这个问题。 – 2014-10-16 01:48:20

你不能强制转换为sortedArrayUsingDescriptors返回一个NSArray的,你需要从阵列中的所有元素复制到斯威夫特类型数组。

func getOrderedWaypoints() -> [OrderWaypoint] { 
    let nameDescriptor = NSSortDescriptor(key: "stop_number", ascending: true) 
    let sorted = [OrderWaypoint]() 
    for elem in self.waypoints.sortedArrayUsingDescriptors([nameDescriptor]) { 
     sorted.append(elem) 
    } 
    return sorted 
} 

而不是做在内存中所有的排序,我通常有获取相关数据直接从像数据库中获取数据,这些辅助方法:

var orderedWayPoints: [WayPoint] { 
    let request = NSFetchRequest(entityName: "Waypoint") 
    request.sortDescriptors = NSSortDescriptor(key: "stop_number", ascending: true) 
    request.predicate = NSPredicate(format: "parent = %@", self) 

    return try! managedObjectContext.executeFetchRequest(request) 
} 

的一点是,我一般希望数据库来完成排序我的数据而不是代码的繁琐工作。而且代码也不多。

最可能的原因是错误是真的:self.waypoints中至少有一个元素实际上不是OrderWaypoint。您可能还有其他类型的内容响应相同的消息。你可能有一个超类OrderWaypoint(你是否使用mogenerator,或许?这些实际上是_OrderWaypoint对象中的任何一个?)你是否在使用它们来描述它们的真实类型? KVO可以做到这一点。

事实上,这在测试目标中失败会提高你嘲笑这些对象的可能性。那可能吗?

我会从仔细检查self.waypoints的内容开始,以确定它实际上是否包含您的想法。

它只会发生在您的测试目标的原因是,它是从主应用程序不同的模块,这样就可以获得不同版本的OrderWaypoint类中的每个模块中,斯威夫特认为是不同类别的:App.OrderWaypointAppTest.OrderWaypoint

我的工作在我自己的项目解决这一点,当我有一个很好的解决方案:)

更新我会更新:对于全斯威夫特的项目,我认为解决方法是删除测试目标中的非测试.swift文件,并将@testable import YourAppModuleName添加到您的Swift测试中。显然这是现代化的方法,无论如何应该可以完成。 (尽管如果你的应用全是Swift,你可能不会有这个问题。)

这对我来说并不适用,因为我有用Objective-C编写的需要访问我的Swift类的测试,而且在导入应用目标的Swift模块时找不到Objective-C等效项。

我的解决方案是重写Objective-C中的问题代码,它不会执行如此严格的类型检查。就我而言,这很容易,因为有问题的函数是最初在Objective-C中声明的类的扩展,所以很容易将它们移动。

更新2:稍微秘密的,但更简单的解决方案是从所述测试对象中删除该应用夫特文件,然后设置头搜索路径在测试目标从应用目标指向DerivedSources夹并在需要它的Objective-C测试中包含App-Swift.h文件,而不是AppTest-Swift.h文件,该文件不再具有应用程序Swift类,因为您只是将它们从测试目标中删除。

+0

你肯定在测试目标中不应该有源文件,但是你不应该在jimmy头部搜索路径中。特别指出派生是荒谬的。 – Rob 2016-07-18 16:06:35

+1

那么我打开替代品。 Objective-C源文件如何从另一个目标访问Swift类的定义? – Uncommon 2016-07-18 19:54:46

+0

这是所有[这里]描述(https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html)。很简单。对不起,如果我听起来像一个工具,我有我的源文件多年的测试目标,并最终打破了它自己。 – Rob 2016-07-18 21:26:57