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.numberOfRows
是 Range
,尤其是 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
不会改变范围(这是一个值类型)或迭代器,因此不会影响迭代次数。
我正在尝试了解 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.numberOfRows
是 Range
,尤其是 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
不会改变范围(这是一个值类型)或迭代器,因此不会影响迭代次数。