You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS16+下NSData转int16_t取值异常问题咨询

问题原因分析与解决方案

问题核心原因

你遇到的问题本质是栈内存越界读取导致的未定义行为:

  • 每个NSData对象存储的是1字节的0-255数值,但代码中用sizeof(int16_t)(即2字节)作为读取长度,试图从1字节的NSData中读取2字节数据,属于越界操作。
  • iOS 15及以前,栈内存中int16_t变量后的1字节恰好是0,读取后int16_t值与原字节值一致;iOS 16+栈布局发生变化,越界读取到的是固定的非0值(如0x73),最终得到原字节值 + 0x73×256的结果,也就是你看到的29440-29696范围。
  • 改成int后看似正常,只是因为64位系统中int为4字节,越界读取时高3字节恰好是0,结果碰巧符合预期,但这依然是未定义行为,存在潜在风险。

能否继续使用int16_t?

可以,但必须修正读取逻辑,避免越界:

方案1:先读取到单字节类型再转换

for(NSData* data in datas)
{
    uint8_t byteValue;
    // 只读取NSData中实际存在的1字节数据
    [data getBytes:&byteValue length:sizeof(byteValue)];
    // 转换为int16_t,自动补高位0,不会出现异常值
    int16_t buff = (int16_t)byteValue;
    NSNumber* number = [NSNumber numberWithInteger:buff];
    [numbers addObject:number];
}

方案2:初始化变量后读取1字节到int16_t

for(NSData* data in datas)
{
    // 先初始化变量为0,避免残留栈值影响
    int16_t buff = 0;
    // 只读取1字节,剩余字节保持初始的0
    [data getBytes:&buff length:1];
    NSNumber* number = [NSNumber numberWithInteger:buff];
    [numbers addObject:number];
}

这两种方法都能确保int16_t获取到正确的0-255范围值,同时符合内存安全规范,在iOS 16+及其他版本中都能稳定运行。

内容的提问来源于stack exchange,提问作者Jater Chu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 23:07:47