Objective-C变量设置不当引发Xcode类型转换告警与App崩溃问题
问题根因
+[NSDecimalNumber decimalNumberWithMantissa:exponent:isNegative:]方法的第一个入参要求是unsigned long long类型的纯数值,而indic[@"amount"]是React-Native桥接层自动包装后的NSNumber *对象(属于id类型),直接传递对象指针给整数类型参数会触发类型不兼容告警,运行时实际传入的是对象的内存地址而非你预期的金额数值,因此会导致逻辑错误甚至崩溃。你在打印时能看到正确数值,是因为Xcode打印id类型对象时会自动调用对象的description方法输出内部存储的数值,不代表参数传递时会自动做类型转换。
解决方案
方案1:先将NSNumber对象转为unsigned long long类型再传入
适合金额数值不会超过unsigned long long取值范围的场景:// 安全取值,避免字典对应key为空的异常 NSNumber *amountNum = indic[@"amount"] ?: @0; unsigned long long mantissa = [amountNum unsignedLongLongValue]; NSDecimalNumber *amount_total = [NSDecimalNumber decimalNumberWithMantissa:mantissa exponent:-2 isNegative:NO];方案2:直接用NSNumber转NSDecimalNumber,无需手动处理mantissa参数
适配大金额场景,代码更简洁不易出错:NSNumber *amountNum = indic[@"amount"] ?: @0; NSDecimalNumber *amount_total = [NSDecimalNumber decimalNumberWithDecimal:amountNum.decimalValue]; // 如果需要固定保留两位小数,可后续追加NSDecimalNumberHandler格式化逻辑
额外注意点
- 若RN侧传递的是字符串格式的金额,可直接使用
[NSDecimalNumber decimalNumberWithString:]方法初始化,避免多次类型转换出现精度损失 - 取值时增加空值默认处理,可规避RN侧漏传参数、参数类型异常导致的崩溃问题
内容的提问来源于stack exchange,提问作者zippax
相关产品推荐
相关产品推荐

