I’ve found a somewhat silly bug. I was curious if anybody could help understand what’s going on.
Imagine my surprise when I stumbled upon this:
One can clearly see there’s a nil check on chartedData, yet it still finds nil.
Putting everything on the main thread solves the bug:
DispatchQueue.main.async {
if chartedData != nil {
cursorIndex = chartedData!.count - 1 // does not crash
}
}
Interesting…
Anyone has any ideas as to what goes on under the hood there ?
In any case, I’m officially twice as paranoid about unwrapping optionals now haha
It means that there is a change to that variable chartedData
occurring after the DispatchQueue has been initiated. DispatchQueue.main.async {
runs concurrently with other code that is executing so it’s likely that by the time the code in DispatchQueue.main.async
closure is executed chartedData has been set to nil.
1 Like
Huh. I guess that makes sense?
With that in mind I found a line earlier in the func where chartedData can sometimes be set to nil. My code was a bit messy and I missed it 
Just in case someone stumbles upon this problem and takes interest, it essentially looked like this:
[... stuff]
DispatchQueue.main.async {
chartedData = somethingThatCanSometimesBeNil
}
[... stuff]
if chartedData != nil {
DispatchQueue.main.async {
cursorIndex = chartedData!.count - 1 // can crash
}
}
I’ll be more careful about this. Thanks a lot Chris!
A better way to write this and use optional is by using a guard
statement instead
guard let chartData else {
return
}
// now you can use chartData without force unwrapping it