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

React Native iOS发布模式点击按钮崩溃,调试模式正常求助

问题排查与修复方案

我一眼就注意到崩溃日志里的关键错误:-[__NSCFNumber length]: unrecognized selector sent to instance——这是典型的把数字类型对象当成字符串调用length方法导致的崩溃,而问题的核心出在你对AsyncStorage的使用上:

React Native的AsyncStorage只支持存储字符串类型的数据,调试模式下RN会帮你做一些隐式的类型转换(比如自动把数字转成字符串),但发布模式下这些调试期的“容错处理”会被优化掉,所以就触发了原生层的异常。

具体问题点

看你代码里的这段逻辑:

}else{
	console.log('if no deleted projects');
	await AsyncStorage.setItem('@TOS:deletedProjects', project.p_id);
}

这里你直接把project.p_id(明显是数字类型)存进了AsyncStorage,没有转成字符串。发布模式下,这个数字会被原生层处理成NSNumber对象,之后当你读取它并尝试做字符串拼接(比如'"' + deletedProjects + '"')时,原生代码会试图调用length方法来处理这个NSNumber,自然就抛出了“无法识别的选择器”异常。

另外,你手动拼接字符串来维护已删除项目ID的方式也很容易出错,比如如果之前存储的格式不规范,后续解析或拼接都会出问题,更稳妥的方式是用数组来管理这些ID,再转成JSON字符串存储。

修复后的代码

// 读取项目列表时,处理getItem返回null的情况,避免JSON.parse报错
let projects = JSON.parse(await AsyncStorage.getItem('@TOS:projects') || '[]');
console.log('projects', projects);
let index = projects.findIndex(x => x.p_id === project.p_id);
console.log(projects, index);

// 先判断index是否有效,防止splice操作报错
if (index !== -1) {
  projects.splice(index, 1);
  console.log('projects', projects);
  await AsyncStorage.setItem('@TOS:projects', JSON.stringify(projects));
}

// 重构已删除项目的处理逻辑,用数组管理ID
let deletedProjects = await AsyncStorage.getItem('@TOS:deletedProjects');
let deletedIds = [];

if (deletedProjects != null) {
  try {
    deletedIds = JSON.parse(deletedProjects);
    // 确保解析后是数组,避免旧数据格式导致的问题
    if (!Array.isArray(deletedIds)) {
      deletedIds = [];
    }
  } catch (e) {
    // 解析失败时重置为空数组
    deletedIds = [];
    console.warn('Failed to parse deleted projects, resetting to empty array', e);
  }
}

// 避免重复添加同一个ID
if (!deletedIds.includes(project.p_id)) {
  deletedIds.push(project.p_id);
}

// 统一转成JSON字符串存储,保证类型一致性
await AsyncStorage.setItem('@TOS:deletedProjects', JSON.stringify(deletedIds));

console.log('in success');

关键注意事项

  1. 强制字符串存储:所有存入AsyncStorage的数据必须是字符串类型,数字、数组、对象都要通过JSON.stringify转换后再存储。
  2. 处理读取异常:读取AsyncStorage时要考虑返回null的情况,以及JSON.parse失败的场景,做好兜底处理。
  3. 避免手动拼接字符串:维护列表类数据时,用数组+JSON序列化的方式比手动拼接字符串可靠得多,能避免格式混乱和类型错误。

内容的提问来源于stack exchange,提问作者Waleed Naveed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:23:57