簡體   English   中英

NSArray元素無法與Swift數組元素類型匹配

[英]NSArray element failed to match the Swift Array Element type

我有一個Core Data對象(Order),它有一個返回另一個Core Data對象(OrderWaypoint)數組的方法。

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
}

但是當我在測試目標中嘗試完全相同的東西時

致命錯誤:NSArray元素無法匹配Swift數組元素類型

我已經嘗試過鑄造這些值,但似乎無法讓它發揮作用。 任何想法為什么它在主要目標而不是測試目標?

編輯

進一步細分它,當我試圖從數組中取出一個項目時,問題就出現了。

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

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

您無法進行類型轉換,因為sortedArrayUsingDescriptors返回NSArray,您需要將該數組中的所有元素復制到Swift Typed數組中。

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類,Swift認為它們是不同的類: App.OrderWaypointAppTest.OrderWaypoint

我正在努力在我自己的項目中解決這個問題,當我有一個很好的解決方案時我會更新:)

更新:對於所有Swift項目,我認為解決方案是從測試目標中刪除非測試.swift文件,並將@testable import YourAppModuleName添加到Swift測試中。 顯然這是現代的方法,無論如何都應該這樣做。 (雖然如果你的應用程序都是Swift,你可能不會遇到這個問題。)

但這對我不起作用,因為我在Objective-C中編寫了需要訪問我的Swift類的測試,而且我很難找到導入應用程序目標的Swift模塊的Objective-C等價物。

我的解決方案是重寫Objective-C中的問題代碼,它不進行這種嚴格的類型檢查。 在我的情況下,這很容易,因為有問題的函數是在最初在Objective-C中聲明的類的擴展中,因此很容易將它們移動。

更新2:一個略顯不足但更簡單的解決方案是從測試目標中刪除應用程序Swift文件,然后將測試目標中的標題搜索路徑設置為指向應用程序目標中的DerivedSources文件夾,並包含App-Swift.h文件在需要它的Objective-C測試中,而不是AppTest-Swift.h文件,它不再有應用程序Swift類,因為你剛從測試目標中刪除它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM