Swift数组(重复:,计数:)行为

时间:2018-01-12 14:43:59

标签: arrays swift

为什么labels数组中只有一个元素显示为view的子视图,特别是在使用Array(repeating:, count:)时?

let labels = Array(repeating: UILabel(), count: 7)

print(labels.count) //7

let view = UIView()

for label in labels {
    view.addSubview(label)
}

print(view.subviews.count) //1

test in the Playground

2 个答案:

答案 0 :(得分:4)

这是Array.init(repeating:count:)的预期行为。将其实现视为:

// not real code! This is just to illustrate what happens!
init(repeating repeatedValue: Array.Element, count: Int) {
    for _ in 0..<count {
        self.append(repeatedValue)
    }
}

此处未创建新标签。只有7个引用指向相同的标签。

无论如何以这种方式创建7个标签是没有用的。它们将处于相同的位置并具有相同的大小text。它看起来好像只有一个标签。所以,只需使用for循环。

修改

这是一个具有您想要的行为的扩展程序:

extension Array {
    init(repeating: (() -> Element), count: Int) {
        self = []
        for _ in 0..<count {
            self.append(repeating())
        }
    }
}

一样使用它
Array(repeating: UILabel.init, count: 7)

由于这在创建标签时不是很有用,我们可以更改闭包类型以包含Int参数。这样我们就可以创建不同的标签:

init(repeating: ((Int) -> Element), count: Int) {
    self = []
    for i in 0..<count {
        self.append(repeating(i))
    }
}

// a horizontal row of square labels!
Array(repeating: { UILabel(frame: CGRect(x: $0 * 100, y: 0, width: 50, height: 50)) })

这种感觉现在就像一个for循环...

答案 1 :(得分:2)

这是因为Array(repeating:count:)创建了一个包含指向相同标签的7个变量的数组。

由于所有7个元素都指向同一个实例,因此子视图的计数将为1。