Swift: For 循环结束条件只计算一次?

Swift: For Loop End Condition Evaluated Only Once?

我正在尝试了解 Swift 如何处理 for-in 循环。

概述:我们正在遍历 NSOutlineView 的行。如果满足条件,我们展开该项目,这显然会改变 outlineView 的总行数。

先决条件:OutlineView 有 5 个“根”项。每个都有 5 个子项。


例子

final class anOutlineView: NSOutlineView
{
    override func reloadData()
    {
        super.reloadData()
        
        for i in 0 ..< self.numberOfRows
        {
            // Assume we expand the item at row 0, which increases 
            // the overall outlineView row count from 5 to 10.
        }
    }
}

在这种方法中,循环在 i == 4 时停止。我假设那是因为 Swift 只评估一次范围,第一次遇到它?有没有办法改变这种行为,以便每次通过循环都重新评估条件,就像传统的 for 循环一样?

while 循环替换 for 循环显然有效,是一个很好的解决方案。我只是想了解 Swift 的细微差别,因为这种行为不是我所期望的。在 Objective-C 中,for 循环条件在每次迭代时都被评估,这是一个众所周知的性能优化,避免在循环条件中调用 self.property(除非有充分的理由存在,因为它在这种情况下。)

0 ..< self.numberOfRowsRange,尤其是 Sequence。迭代一个序列是通过创建一个迭代器来完成的,然后调用它的 next() 方法直到迭代器耗尽,比较 IteratorProtocol:

Whenever you use a for-in loop with an array, set, or any other collection or sequence, you’re using that type’s iterator. Swift uses a sequence’s or collection’s iterator internally to enable the for-in loop language construct.

所以

for i in 0 ..< self.numberOfRows {
    ...
}

相当于

let range = 0 ..< self.numberOfRows
var it = range.makeIterator()
while let i = it.next() {
    ...
}

在迭代期间修改 numberOfRows 不会改变范围(这是一个值类型)或迭代器,因此不会影响迭代次数。