前几天遇到一个问题,将uint32_t类型的值放到字典里面传递到下一个vc中。就这么个简单的问题,却踩进了坑。

由于之前主攻java,想当然的就将uint32_t转换成NSString然后丢到下一个vc中,然后要使用的时候再转回uint32_t,然后问题就出现了:转回uint32_t后发现数值不正确。

下面是之前的转换方式:

//uint32_t --> NSString
uint32_t a=2373916479;
NSString * aStr=[NSString stringWithFormat:@"%u",a];//这个没毛病,确实变成了字符串
//NSString --> uint32_t
uint32_t b=[aStr intValue];//这句话有问题

通过上面的代码执行后发现a和b的值不一样,惊到我了!

通过查询uint32_t的定义,发现这货就是unsigned int。然后再回来看代码,觉得没问题哇。。。

然后再转念一想,它是无符号的int,直接转数值会有损。于是将最后一句改成:

uint32_t b=[aStr longLongValue];

虽然执行结果正确了,但是xcode提示了一个警告:

Implicit conversion loses integer precision:'long long' to 'uint32_t' (aka 'unsigned int')

虽然能解决问题,但是这个警告实在是看的很不爽,而且实现起来比较暴力。怎样才能更加优雅的解决目前的困扰呢?

搜索了StackOverflow,突然发现可以把uint32_t放到NSNumber中,再放到字典里面,于是:

//uint32_t --> NSNumber
uint32_t a=2373916479;
NSNumber * aNumber=[NSNumber numberWithUnsignedInt:a];//用NSNumber包裹uint32_t,这样就能放到字典中了
//NSNumber --> uint32_t
uint32_t b=[aNumber unsignedIntValue];//结果正确

经过上面的实践之后,总结一下:

  1. 一切都是基础不扎实导致的
  2. uint32_t本质是unsigned int,如果先转化为字符串再用intValue转回来就会有可能出现数据不正确的情况,而且NSString也没有提供unsingedIntValue,所以使用NSString不明智;
  3. NSNumber是一个可以放到字典和数组中的类型。如果需要再字字典或者数组中存放基本数据类型,可以把所需要的基本数据类型转化为NSNumber后再存入