It looks like the following Swift for-in loop is trying to go through more elements than are in the array.
For instance, this code:
var list:[Int?] = [1,2,3,4,5,6,7]
print("C-Style for loop")
for var i=0; i<list.count; i++
{
var x:Int = list[i]!
print(x)
}
print("\nFor-in loop")
for var x:Int! in list
{
print(x)
}
Gets this output:
C-Style for loop
1
2
3
4
5
6
7
For each loop
1
2
3
4
5
6
7
fatal error: unexpectedly found nil while unwrapping an Optional value
...
Illegal instruction: 4
I must be missing something here. Shouldn't list.count
be the number of elements that the for-in loop tries to unwrap?
Not pictured above, the for-in loop works as expected if use an [Int]
list instead of [Int?]
with no unwrapping.
I am on Swift version 2.1.1.
Basically you've done something you're not supposed to do, and thus you've stumbled on something that's probably a compiler bug (because the compiler didn't stop you). Very nice!
Now the solution. You are evidently trying to unwrap with your Int!
. To unwrap safely, use for case
syntax:
let list:[Int?] = [1,2,3,4,5,6,7]
for case let x? in list
{
print(x) // 1, 2, 3, 4, 5, 6, 7
}
Another way (same result):
let list:[Int?] = [1,2,3,4,5,6,7]
list.flatMap{$0}.forEach{print($0)} // 1, 2, 3, 4, 5, 6, 7
Forced Unwrapping like x:Int!
is a dangerous coding style when you can't rule out nil. The same holds for var x:Int = list[i]!
.
This works:
print("\nFor-in loop")
for x in list {
print(x)
}
Here you allow x to be nil and can safely check for nil later.
Now to the question why your code breaks:
Internally, swift uses list.generate()
for the for-in loop. Generators are nil terminated which is probably the reason why your code breaks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With