我正在阅读Swift文档,看看关于类型转换的部分。
文档谈到从Foundation框架东西(在Objective-C中是一个NSArray *)获取一个类型为[AnyObject]的数组。
首先,文档提供了这个例子:
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从一个[AnyObject]下拉到一个[Movie],所以我们不必在循环中向下转换。
这让我想,可以数组作为一个整体选择downcast?
if let someMovies = someObjects as? [Movie] { for movie in someMovies { println("Movie: '\(movie.name)',dir. \(movie.director)") } }
这工作吗?如果是,从性能的角度来看,这有多糟糕?使用可选的向下转换在10,000个元素数组中检查每个对象的类型需要多长时间?
我理解这段代码和我以前的可选下行代码段之间的影响是不同的。第一个将遍历每个对象,并只尝试打印,如果对象是一个电影,其中第二个将只进入循环,如果数组可以向下转换到一个[电影]数组,在这种情况下,它将打印所有或无,但我可以想象有些情况下,这是更可取的。
你有它 – 它的工作原理就像你的示例代码:
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]"
不知道性能,但我不会假设它将必须通过遍历整个数组,以确定是否可能的downcast。
所以我很好奇,并在一个几个不同的[AnyObject]配置中运行一个快速测试与100,000个简单的值,其中我试图将数组向下转换为一个[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元素。对于可以向下转换的数组,它显然必须遍历整个数组,并且需要更长的时间,虽然我不知道为什么它不是循环通过数组和手动检查每个元素的速度。