This is one of those rare jewels of a bug that will cost you days to figure out if you encounter it in the context of a large app. It makes you doubt our own sanity until you come to the painful conclusion that the problem indeed resides in Apple’s code, not yours.
In this special case we had a couple of rare circumstances that worked together to form a scenario where CGRectMakeWithDictionaryRepresentation partially fails to reconstitute a CGRect from a dictionary. This function is literally ancient, it exists since iOS 2 and Mac OS 10.5. This makes it even more implausible that nobody has stumbled across this before us.
In the project where we first saw the problem these where the steps that led to this bug’s discovery:
- Create a CGRect that is not an integer
- Write a dictionary from iOS simulator which contains a dictionary encoding this CGRect
- Open this dictionary in Xcode’s property list editor
- Upon saving some of the least significant digits change in the “real” items
- This new dictionary can no longer be parsed on iOS
What’s even funnier is that some such modified values can still be read, but then the function fails internally and the remaining values don’t get parsed, i.e. stay zero.
From what I have seen researching this bug looks like certain floating point numbers cannot be represented on iOS. The normal parsing functions are able to round to the closest value that can be represented in 32-bit floats, whereas CGRectMakeWithDictionaryRepresentation fails to do so. The first value that cannot be exactly represented is truncated, all following values turn out to be Zero.
This was filed as rdar://12358120 and on OpenRadar.