Swift のドキュメントを読んでいて、型キャストに関するセクションを見ています。
[AnyObject]
ドキュメントでは、Foundation フレームワークのもの ( NSArray *
Objective-C では )から型の配列を取得する方法について説明しています。
まず、ドキュメントには次の例が示されています。
for object in someObjects {
let movie = object as Movie
println("Movie: '\(movie.name)', dir. \(movie.director)")
}
ここで、例を少し変更して、すべてのオブジェクトが 型であるかどうかわからないケースに変更します。Movie
次のようにします。
for object in someObject {
if let movie = object as? Movie {
println("Movie: '\(movie.name', dir. \(movie.director)")
}
}
ドキュメントでは、最初のループを記述するより良い方法の例が示されています。
for movie in someObjects as [Movie] {
println("Movie: '\(movie.name)', dir. \(movie.director)")
}
ループ内でダウンキャストする必要がないように、someObjects
an から[AnyObject]
a にダウンキャストします。[Movie]
そして、私は考えました。配列全体をオプション ダウンキャストできるのでしょうか?
if let someMovies = someObjects as? [Movie] {
for movie in someMovies {
println("Movie: '\(movie.name)', dir. \(movie.director)")
}
}
これは機能しますか? 機能する場合、パフォーマンスの観点からはどの程度悪いでしょうか? オプションのダウンキャストを使用して 10,000 要素の配列内のすべてのオブジェクトの型を確認するには、どのくらいの時間がかかりますか?
このスニペットと、以前のオプションのダウンキャスト スニペットの意味合いが異なることは理解しています。最初のスニペットはすべてのオブジェクトを反復処理し、オブジェクトが である場合にのみ印刷を試行しますがMovie
、2 番目のスニペットは、配列を配列にダウンキャストできる場合にのみループに入り[Movie]
、その場合はすべてを印刷するか、何も印刷しませんが、これが望ましい状況もあると思います。
ベストアンサー1
そうです、サンプルコードとまったく同じように動作します:
let strings = ["Hi", "Hello", "Aloha"]
let anyObjects: [AnyObject] = strings
if let downcastStrings = anyObjects as? [String] {
println("It's a [String]")
}
// console says "It's a [String]"
パフォーマンスについてはわかりませんが、ダウンキャストが可能かどうかを判断するために配列全体を反復処理する必要はないと思います。
そこで私は興味を持ち、いくつかの異なる[AnyObject]
構成で 100,000 個の単純な値を使用して簡単なテストを実行しました。ここでは、配列を a にダウンキャストする[String]
か、個々の要素をダウンキャストするかを試しています。
// var anyObjects: [AnyObject] = [AnyObject]()
// filled with random assortment of Int, String, Double, Bool
Running test with mixed array
downcast array execution time = 0.000522
downcast elements execution time = 0.571749
// var actuallyStrings: [AnyObject] = [AnyObject]()
// filled with String values
Running test with all strings
downcast array execution time = 1.141267
downcast elements execution time = 0.853765
混合配列をダウンキャスト不可能として破棄するのは、非要素が見つかるまでスキャンするだけで済むので、非常に高速であるように見えますString
。できるdowncast では、明らかに配列全体を処理する必要があり、時間がかかります。ただし、配列をループして各要素を手動でチェックするのと同じ速度にならない理由はわかりません。