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

Cam*_*ron 3 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
Run Code Online (Sandbox Code Playgroud)

在操场上测试

Tam*_*gel 7

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

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


Swe*_*per 5

这是的预期行为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)
    }
}
Run Code Online (Sandbox Code Playgroud)

在这里,没有创建新标签。只有7个引用指向相同的标签。

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

编辑

这是具有所需行为的扩展:

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

像这样使用

Array(repeating: UILabel.init, count: 7)
Run Code Online (Sandbox Code Playgroud)

由于这在创建标签中不是很有用,因此我们可以更改闭包类型以包含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)) })
Run Code Online (Sandbox Code Playgroud)

现在有点像for循环了...