每次访问getter时,这个for循环是否会触发?或者Swift在幕后缓存它' ?
var colors: [UIColor] {
get {
var colors = [UIColor]()
let palette = [UIColor.redColor(), UIColor.greenColor(), UIColor.blueColor(), UIColor.orangeColor(), UIColor.purpleColor(), UIColor.yellowColor()]
var paletteIndex = 0
for _ in 0..<photos.count {
colors.append(palette[paletteIndex])
paletteIndex = paletteIndex == (palette.count - 1) ? 0 : ++paletteIndex
}
return colors
}
}
在objective-c中,像这样的吸气剂将位于私人ivar的支票后面,这样ivar就会被设置一次,然后ivar会在后续的呼叫中返回。
答案 0 :(得分:2)
每次调用getter时都会触发。绝不可能将其优化掉。
您可能希望将预设颜色数组与照片属性保持同步,即在设置照片时直接更改。
我也不喜欢那个地方紧密耦合似乎没必要。我认为重构这个并且只返回给定照片索引的特定颜色(使用模运算符是微不足道的)可能是值得的。
所以我的建议是将调色板保存为实例变量,然后制作方法return palette[index % palette.count]
,它会立即给出正确的颜色。
答案 1 :(得分:1)
我将这样做,正如@Eiko所建议的
let palette = [UIColor.redColor(), UIColor.greenColor(), UIColor.blueColor(), UIColor.orangeColor(), UIColor.purpleColor(), UIColor.yellowColor()]
override func viewDidLoad() {
super.viewDidLoad()
...
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("AnnotatedPhotoCell", forIndexPath: indexPath) as UICollectionViewCell
cell.contentView.backgroundColor = palette[indexPath.item % palette.count]
return cell
}
答案 2 :(得分:0)
您使用的computed property
实际上并未存储值,并且计算的命名值或计算属性的值不会存储在内存中。它在快速的编程书中
答案 3 :(得分:0)
您可以使用延迟初始化:
lazy var colors : [UIColor] = {
var colors = [UIColor.redColor]
// blablabla
return colors
}()
当您第一次尝试访问颜色时,它将只运行一次。但是,如果颜色需要在整个课程期间更新,我建议使用函数重新计算它们:
func recalcColors() -> [UIColor] {
var colors = [UIColor.redColor]
// blablabla
return colors
}
lazy var colors = recalcColors()
当您需要更新它们时,您可以拨打colors = recalcColors()
答案 4 :(得分:0)
从Swift逻辑的角度来看,它每次都会运行,但是,在某些情况下,优化器可以将整个计算转换为常量,在这种情况下无关紧要。
有两件事阻碍了它:palette
数组和photos.count
属性。从理论上讲,palette
数组永远不会改变,但编译器无法知道这一点,因为它不知道像redColor()
这样的函数总是返回相同的值。因此,将数组创建提升到属性之外。
photos.count
可能没有修复,假设photos
在程序过程中动态变化大小。
但这会给你带来同样的效果,根本不需要创建任何数组:
struct PaletteCycler {
let palette = [
UIColor.redColor(), UIColor.greenColor(),
UIColor.blueColor(), UIColor.orangeColor(),
UIColor.purpleColor(), UIColor.yellowColor(),
]
subscript(idx: Int)->UIColor {
return palette[idx%palette.count]
}
}
let colors = PaletteCycler()
由于一切都是常量,因此获取颜色的运行时成本非常低。与原始版本不同,这不会每次都创建一个数组。由于mod和fetch非常有效,并且palette
变量是常量,因此它应该很快。
顺便说一下,如果事情不那么稳定并且你真的想要一个数组,你可以使用map重写你的循环:
let palette = [
UIColor.redColor(), UIColor.greenColor(),
UIColor.blueColor(), UIColor.orangeColor(),
UIColor.purpleColor(), UIColor.yellowColor(),
]
var colors: [UIColor] = {
// Swift 2.0 syntax. For 1.2, write
// indices(photos).map
return photos.indices.map {
palette[$0 % palette.count]
}
}