ios 如何将 NSMutableArray 转换为特定类型的 Swift 数组?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25837539/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I cast an NSMutableArray to a Swift array of a specific type?
提问by Tom van Zummeren
I am migrating my iOS project to Swift. I am doing this class by class. When I call Objective C methods from Swift, a lot of Objective C types are converted to their Swift counterparts.
我正在将我的 iOS 项目迁移到 Swift。我正在逐个上课。当我从 Swift 调用 Objective C 方法时,很多 Objective C 类型被转换为它们的 Swift 对应类型。
In my case an Objective C NSMutableArray
gets converted to Swift's Array<AnyObject>
. Now here comes my problem. Within my Swift class, I get such an array back from an Objective C object. Now that I am in the Swift world, I would like to cast this array to a specific type instead of AnyObject
, because I know for sure what kind of objects exist in this array.
在我的情况下,Objective CNSMutableArray
被转换为 Swift 的Array<AnyObject>
. 现在我的问题来了。在我的 Swift 类中,我从一个 Objective C 对象中得到了这样一个数组。现在我在 Swift 世界中,我想将这个数组转换为特定类型而不是AnyObject
,因为我确定这个数组中存在什么样的对象。
The compiler won't let me do that! Let me simplify my problem by saying I want to cast to an array containing strings. This is what I tried:
编译器不会让我这样做!让我通过说我想转换为包含字符串的数组来简化我的问题。这是我尝试过的:
var strings = myObjcObject.getStrings() as [String]
I get the following error from the compiler:
我从编译器收到以下错误:
'String' is not identical to 'AnyObject'
“String”与“AnyObject”不同
I would have to agree with the compiler, since String is indeed not identical to AnyObject. But I don't see why that is a problem. I can downcast AnyObject to String if I want, right?
我不得不同意编译器,因为 String 确实与 AnyObject 不同。但我不明白为什么这是一个问题。如果我愿意,我可以将 AnyObject 向下转换为 String,对吗?
I also tried:
我也试过:
var strings = myObjcObject.getStrings() as? [String]
This seems to be a step in the right direction, but getStrings() returns an NSMutableArray
so I get the following error:
这似乎是朝着正确方向迈出的一步,但 getStrings() 返回一个,NSMutableArray
所以我收到以下错误:
'NSArray' is not a subtype of 'NSMutableArray'
“NSArray”不是“NSMutableArray”的子类型
Is there any way to do what I am trying to do here?
有什么办法可以做我在这里想做的事情吗?
回答by Mike S
You can make this work with a double downcast, first to NSArray
, then to [String]
:
您可以通过双重向下转换来完成这项工作,首先是 to NSArray
,然后是[String]
:
var strings = myObjcObject.getStrings() as NSArray as [String]
Tested in a Playground with:
在 Playground 中测试:
import Foundation
var objCMutableArray = NSMutableArray(array: ["a", "b", "c"])
var swiftArray = objCMutableArray as NSArray as [String]
Update:
更新:
In later versions of Swift (at least 1.2), the compiler will complain about as [String]
. Instead you should use an if let
with a conditional downcast as?
:
在 Swift 的更高版本(至少 1.2)中,编译器会抱怨as [String]
. 相反,您应该使用if let
带有条件向下转换的an as?
:
import Foundation
var objCMutableArray = NSMutableArray(array: ["a", "b", "c"])
if let swiftArray = objCMutableArray as NSArray as? [String] {
// Use swiftArray here
}
If you are absolutelysure that your NSMutableArray
can be cast to [String]
, then you can use as!
instead (but you probably shouldn't use this in most cases):
如果您绝对确定您NSMutableArray
可以强制转换为[String]
,那么您可以as!
改为使用(但在大多数情况下您可能不应该使用它):
import Foundation
var objCMutableArray = NSMutableArray(array: ["a", "b", "c"])
var swiftArray = objCMutableArray as NSArray as! [String]
回答by Simon Rice
compactMap
is your friend in Swift 4.1 and above, as well as in Swift 3.3-3.4 for that matter. This means that you don't have any double or forced casting.
compactMap
是您在 Swift 4.1 及更高版本以及 Swift 3.3-3.4 中的朋友。这意味着您没有任何双重或强制转换。
let mutableArray = NSMutableArray(array: ["a", "b", "c"])
let swiftArray: [String] = mutableArray.compactMap { let swiftArray: [String] = mutableArray.flatMap { let mutableArray = NSMutableArray()
mutableArray.add("Abc")
mutableArray.add("def")
mutableArray.add("ghi")
if let array = mutableArray as? [String] {
print(array) // ["Abc", "def", "ghi"]
}
as? String }
as? String }
In previous versions of Swift, 2.0-3.2 and 4.0, you'll want to use flatMap
for this purpose. The usage is the same as compactMap
:
在之前的 Swift 版本 2.0-3.2 和 4.0 中,您会希望使用flatMap
此功能。用法与以下相同compactMap
:
let mutableArray = NSMutableArray(array: ["a", "b", "c"])
let swiftArray = NSArray(array: mutableArray) as? [String]
回答by Leo Dabus
var mutableArray = NSMutableArray(array:"1", "2", "3")
let swiftArray = mutableArray as AnyObject as! [String]
回答by average Joe
With Swift 1.2 the following will work:
使用 Swift 1.2,以下内容将起作用:
let array: [String] = nsMutableArrayObject.copy() as! [String]
回答by Nazariy Vlizlo
in Xcode 6.3 i used the following:
在 Xcode 6.3 中,我使用了以下内容:
(imagesField!.images as! [UIImage])
回答by Amr Angry
for swift 3
快速 3
you may consider the following code
你可以考虑下面的代码
public static func cast(_ object: Any) -> Self {
return object as! Self
}
回答by Renetik
In my case compiler wanted me to write it like this to suppress all warnings and compilation problems, so not just that exclamation marks even if field imagesField is already declared with one, but also parentheses and "as!" to make it sure that nobody complains.
在我的例子中,编译器希望我这样写以抑制所有警告和编译问题,所以不仅是感叹号,即使字段 imagesField 已经声明为一个,而且还有括号和“as!” 以确保没有人抱怨。
extension Array: CSLang {
}
It made me quite uncomfortable... Swift could be nicer, its new language so... I made extension:
这让我很不舒服...... Swift 可能会更好,它的新语言所以......我做了扩展:
[UIImage].cast(imagesField.images)
Assigned it to Array:
将其分配给数组:
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])
}
And now I can write the same statement like this with the same effect:
现在我可以用同样的效果写出同样的语句:
##代码##Like it or not, this is my way, less question and exclamation marks, better. I made also unit test:
不管你喜不喜欢,这就是我的方式,少问号和感叹号,更好。我也做了单元测试:
##代码##