My app remembers MPMediaItems by persistentId, as one does. It saves the persistentId in a JSON file, which is later read and parsed. NSJSONSerialization creates an NSDecimalNumber to contain the Id, which my app later uses in an MPMediaQuery to get the MPMediaItem.
What I found is that sometimes the wrong MPMediaItem is found. When I poked around some more, I discovered that when I convert the NSDecimalNumber to a uint64_t value, [NSNumber unsignedLongLongValue] returns the wrong value!
NSDecimalNumber* const songId = _songId;
uint64_t const songIdValue = songId.unsignedLongLongValue;
songId is 1457249251113381177
songIdValue is 1457249251113381120
-or-
songId is 0x1439307919d12d39
songIdValue is 0x1439307919d12d00
What the heck? It looks like the low byte is getting cleared in the conversion of this NSDecimalNumber to a uint64_t. Is this somehow correct behavior for NSDecimalNumber of have I found a bug in it?
I'm working around this by converting the NSDecimalNumber from NSJSONSerialization to a string and converting the string to a uint64_t with [NSString longLongValue].
It's scary in that it seems I now have go and check EVERY place I store large integers in JSON files and make sure I evaluate them in this NSString-y way.