JSON对象转NSData再转回后NSNumber值变更问题求助
Let's figure out why your price value (originally set to 106 as an NSNumber) is getting altered when you serialize your dictionary to NSData and deserialize it back to a JSON object. Below are the most common causes and actionable fixes to resolve this issue:
Common Causes & Fixes
1. Accidental Floating-Point Conversion
JSON doesn’t natively distinguish between integers and floats. When NSJSONSerialization deserializes numeric values, it returns NSNumber instances—but if your original price was stored as a float (e.g., @(106.0) instead of @106), deserialization might keep it as a float. While 106.0 represents the same value, this could look like a "change" if you’re expecting an integer type. In rare cases, floating-point precision errors might skew the value (though this is unlikely with a small integer like 106).
Fix:
Initialize the price explicitly as an integer to avoid ambiguity:
// Correct integer initialization for price paramDict[@"storeInfo"][@"qrCodeInfo"][@"price"] = @106; // Or use [NSNumber numberWithInteger:106]; for older syntax
When deserializing, explicitly cast back to an integer type to eliminate any floating-point confusion:
NSDictionary *deserializedDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil]; NSInteger price = [deserializedDict[@"storeInfo"][@"qrCodeInfo"][@"price"] integerValue]; // This will reliably return 106, even if the NSNumber is stored as a float
2. Unhandled Serialization/Deserialization Errors
You’re passing nil for the error parameter in both serialization and deserialization calls. If there’s a hidden error (like invalid types in your dictionary), the resulting NSData could be malformed, leading to incorrect values when deserialized.
Fix:
Always check for errors to catch issues early:
// Serialization with error checking NSError *serializationError = nil; NSData *data = [NSJSONSerialization dataWithJSONObject:paramDict options:kNilOptions error:&serializationError]; if (serializationError) { NSLog(@"Serialization failed: %@", serializationError.localizedDescription); // Handle the error (e.g., fix invalid dictionary entries) } // Deserialization with error checking NSError *deserializationError = nil; NSDictionary *deserializedDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&deserializationError]; if (deserializationError) { NSLog(@"Deserialization failed: %@", deserializationError.localizedDescription); // Handle the error (e.g., check for corrupted data) }
3. Unexpected Type in the Original Dictionary
Double-check that the price value in your original paramDict is actually an NSNumber. If you accidentally stored it as a string (e.g., @"106"), deserialization will keep it as a string, which might look like a value change if you’re expecting a number.
Fix:
Validate the type before serialization to catch mismatches:
id priceValue = paramDict[@"storeInfo"][@"qrCodeInfo"][@"price"]; if ([priceValue isKindOfClass:[NSNumber class]]) { NSLog(@"Price is a valid NSNumber: %@", priceValue); } else { NSLog(@"Unexpected type for price: %@", [priceValue class]); // Correct the type here (e.g., convert string to NSNumber) }
4. Quick Test to Isolate the Issue
Run this minimal test with your exact dictionary structure to verify if the round-trip works as expected. If this test outputs correct values, the problem is likely in how you’re building your original paramDict elsewhere in your code:
// Build your exact dictionary NSDictionary *paramDict = @{ @"channelId": @201, @"lang": @"EN", @"reqRefNo": @"vZRIzNd", @"storeInfo": @{ @"clientInfo": @{ @"deviceId": @"XXXXXXXXA67F488B836D19D80EC4FD8D" }, @"loginLogId": @"XXXXXXXX5CAD4A0DA06BE2F055929856", @"qrCodeInfo": @{ @"itemDesc": @"", @"itemName": @"hahsj", @"price": @106 }, @"userInfo": @{ @"storeId": @3252 } } }; // Serialize NSError *error = nil; NSData *data = [NSJSONSerialization dataWithJSONObject:paramDict options:kNilOptions error:&error]; if (error) { NSLog(@"Serialize error: %@", error); return; } // Deserialize NSDictionary *deserialized = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error]; if (error) { NSLog(@"Deserialize error: %@", error); return; } // Verify price NSNumber *price = deserialized[@"storeInfo"][@"qrCodeInfo"][@"price"]; NSLog(@"Original price: %@ | Deserialized price: %@ | Integer value: %ld", @106, price, (long)[price integerValue]);
内容的提问来源于stack exchange,提问作者Sanket_B

