Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
283 views
in Technique[技术] by (71.8m points)

ios - How can I cast an NSMutableArray to a Swift array of a specific type?

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.

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.

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'

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?

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:

'NSArray' is not a subtype of 'NSMutableArray'

Is there any way to do what I am trying to do here?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You can make this work with a double downcast, first to NSArray, then to [String]:

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

Tested in a Playground with:

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?:

import Foundation

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

If you are absolutely sure that your NSMutableArray can be cast to [String], then you can use as! instead (but you probably shouldn't use this in most cases):

import Foundation

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...