簡體   English   中英

如何將NSMutableArray轉換為特定類型的Swift數組?

[英]How can I cast an NSMutableArray to a Swift array of a specific type?

我正在將我的iOS項目遷移到Swift。 我是按班做的。 當我從Swift調用Objective C方法時,許多Objective C類型被轉換為它們的Swift對應物。

在我的例子中,Objective C NSMutableArray被轉換為Swift的Array<AnyObject> 現在我的問題來了。 在我的Swift類中,我從Objective C對象中獲取了這樣一個數組。 現在我在Swift世界中,我想將此數組轉換為特定類型而不是AnyObject ,因為我確定該數組中存在哪種對象。

編譯器不會讓我這樣做! 讓我通過說我想要轉換為包含字符串的數組來簡化我的問題。 這是我試過的:

var strings = myObjcObject.getStrings() as [String]

我從編譯器得到以下錯誤:

'String'與'AnyObject'不同

我必須同意編譯器,因為String確實與AnyObject不同。 但我不明白為什么這是一個問題。 如果我願意,我可以將AnyObject轉發給String,對吧?

我也嘗試過:

var strings = myObjcObject.getStrings() as? [String]

這似乎是朝着正確方向邁出的一步,但getStrings()返回一個NSMutableArray因此我收到以下錯誤:

'NSArray'不是'NSMutableArray'的子類型

有沒有辦法做我想在這里做的事情?

您可以使用雙向下轉換,首先使用NSArray ,然后使用[String]

var strings = myObjcObject.getStrings() as NSArray as [String]

在游樂場測試:

import Foundation

var objCMutableArray = NSMutableArray(array: ["a", "b", "c"])
var swiftArray = objCMutableArray as NSArray as [String]

更新:

在Swift的后續版本(至少1.2)中,編譯器會抱怨as [String] 相反,你應該使用if let with條件downcast as?

import Foundation

var objCMutableArray = NSMutableArray(array: ["a", "b", "c"])
if let swiftArray = objCMutableArray as NSArray as? [String] {
    // Use swiftArray here
}

如果您完全確定您的NSMutableArray可以NSMutableArray[String] ,那么您可以使用as! 相反(但在大多數情況下你可能不應該使用它):

import Foundation

var objCMutableArray = NSMutableArray(array: ["a", "b", "c"])
var swiftArray = objCMutableArray as NSArray as! [String]

compactMap是您在Swift 4.1及更高compactMap中的朋友,也是Swift 3.3-3.4中的朋友。 這意味着您沒有任何雙重或強制轉換。

let mutableArray = NSMutableArray(array: ["a", "b", "c"])
let swiftArray: [String] = mutableArray.compactMap { $0 as? String }

在以前版本的Swift,2.0-3.2和4.0中,您將需要使用flatMap來實現此目的。 用法與compactMap相同:

let swiftArray: [String] = mutableArray.flatMap { $0 as? String }

使用Swift 1.2,以下內容將起作用:

let mutableArray = NSMutableArray(array: ["a", "b", "c"])
let swiftArray = NSArray(array: mutableArray) as? [String]
let mutableArray = NSMutableArray()

mutableArray.add("Abc")
mutableArray.add("def")
mutableArray.add("ghi")

if let array = mutableArray as? [String] {
    print(array)    // ["Abc", "def", "ghi"]
}

在Xcode 6.3中,我使用了以下內容:

var mutableArray = NSMutableArray(array:"1", "2", "3")
let swiftArray = mutableArray as AnyObject as! [String]

對於斯威夫特3

您可以考慮以下代碼

let array: [String] = nsMutableArrayObject.copy() as! [String]

在我的情況下,編譯器希望我這樣編寫它來抑制所有警告和編譯問題,所以即使字段imagesField已經用一個聲明,而且括號和“as!”,也不僅僅是感嘆號。 確保沒有人抱怨。

(imagesField!.images as! [UIImage]) 🤮

這讓我感到非常不舒服......斯威夫特可能更好,它的新語言如此...我做了擴展:

 public static func cast(_ object: Any) -> Self {
        return object as! Self
    }

將其分配給Array:

extension Array: CSLang {
}

現在我可以用相同的效果編寫相同的語句:

[UIImage].cast(imagesField.images)

喜歡與否,這是我的方式,更少的問題和感嘆號,更好。 我做了單元測試:

func testCast() {
    let array: NSMutableArray? = NSMutableArray()
    array?.add("test string 1")
    array?.add("test string 2")
    let stringArray: [String] = [String].cast(array)
    XCTAssertEqual("test string 2", stringArray[1])
}

暫無
暫無

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

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