IOS KVC 32位和64位的坑

探讨了在不同位数的编译环境下,利用KVC进行JSON反序列化时遇到的异常问题及其解决方案,包括调整后台接口返回的数据格式、修改实体字段类型等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实体定义了个字段id,并通过KVC将json反序列化。

@property (nonatomic, assign) long id;
测试人员提出在iPad Mini ios9.3下闪退。调试发现在调用KVC方法setValuesForKeysWithDictionary:时崩溃了,抛出异常:

NSInvalidArgumentException -[__NSCFString longValue]: unrecognized selector sent to instance

查找资料发现了问题出在32位和64位上

32位编译器
char :1个字节
char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节。同理64位编译器)
short int : 2个字节
int:  4个字节
unsigned int : 4个字节
float:  4个字节
double:   8个字节
long:   4个字节
long long:  8个字节
unsigned long:  4个字节

64位编译器
char :1个字节
char*(即指针变量): 8个字节
short int : 2个字节
int:  4个字节
unsigned int : 4个字节
float:  4个字节
double:   8个字节
long:   8个字节
long long:  8个字节

先说说64位下运行正常的原因:

在64位下long类型和long long类型都是8个字节,所以64位下id实际类型是long long


而后台返回的json是:{"id":"1"},即id属性是NSString,所以需要将NSString转换成long long类型,NSString转换的相关方法有

@property (readonly) int intValue;
@property (readonly) NSInteger integerValue NS_AVAILABLE(10_5, 2_0);
@property (readonly) long long longLongValue NS_AVAILABLE(10_5, 2_0);
于是通过KVC赋值时通过longLongValue转换成功。

而在32位下,long类型是4个字节,long long类型是8个字节。所以在将NSString转换成long时试图访问longValue属性时报错。


解决方法:

1、后台接口返回json时id值不带双引号,即{"id":1},这样不需要从NSString转换成long类型

2、id字段使用NSInteger类型,NSInteger定义如下:

#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif
即在32位下时int,64位下是long,所以32位下NSString转换成int 访问intValue属性即可
3、id字段使用long long类型,都是8个字节。推荐使用,因为后台字段也是Long类型,防止转换时溢出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值