无法为可空变量userCurrentPosition赋值,触发空检查错误求助
需求:若变量lat已有值,则避免调用locateUserPosition()函数。由于该值存储在SharedPreferences中,使用Timer预留读取时间。
当前问题:从SharedPreferences读取的lat和lng已有值,但执行userCurrentPosition?.latitude = lat!;和userCurrentPosition?.longitude = lng!;后,userCurrentPosition仍为null,打印时触发_CastError (Null check operator used on a null value)错误。
代码片段:
initState() { super.initState(); dataFuture = getData(); if (lat == null) { Timer(Duration(seconds: 1), () { if (lat == null) { print('location is null'); locateUserPosition(); } else { userCurrentPosition?.latitude = lat!; userCurrentPosition?.longitude = lng!; // After running the two above lines, where lat and lng both have values, // they still couldn't be assigned to the userCurrentPosition.latitude and // userCurrentPosition.longitude. The next line shows this error // _CastError (Null check operator used on a null value) print('usercurrentposition: ${userCurrentPosition!.latitude}'); // <- error here } }); // EasyLoading.showSuccess('Use in initState'); // debugPrint("radius: $radius"); } else { userCurrentPosition?.latitude = lat!; userCurrentPosition?.longitude = lng!; // EasyLoading.showSuccess('Use in initState'); // debugPrint("radius: $radius"); } // setState(() {}); }
编辑补充:运行时lat和lng均有值,但赋值后userCurrentPosition的latitude和longitude仍为null,打印时抛出上述错误。
问题原因与解决方案
核心原因
userCurrentPosition初始值为null,你使用了?.操作符赋值属性——这个操作符的规则是如果对象为null,直接跳过后续代码执行。所以你写的userCurrentPosition?.latitude = lat!;根本没有执行,userCurrentPosition始终是null,最后用!强制解包null自然触发空指针错误。
解决方案
先初始化userCurrentPosition对象
不要试图给null对象的属性赋值,直接创建实例并传入经纬度:// 假设userCurrentPosition是LatLng类型,直接初始化 userCurrentPosition = LatLng(lat!, lng!);代替原来的分步属性赋值操作。
抛弃Timer,改用异步读取SharedPreferences
Timer等待1秒的方式完全不可靠(读取耗时不确定),正确的做法是在initState中调用异步函数读取SharedPreferences:@override void initState() { super.initState(); dataFuture = getData(); // 调用异步读取方法 _loadSavedLocation(); } void _loadSavedLocation() async { // 读取SharedPreferences的逻辑 final prefs = await SharedPreferences.getInstance(); lat = prefs.getDouble('lat'); lng = prefs.getDouble('lng'); if (lat == null || lng == null) { locateUserPosition(); } else { // 初始化userCurrentPosition userCurrentPosition = LatLng(lat!, lng!); print('usercurrentposition: ${userCurrentPosition!.latitude}'); // 如果需要更新UI,调用setState setState(() {}); } }
额外说明
- 如果你需要在UI中使用
userCurrentPosition,记得在赋值后调用setState(() {})触发组件重建。 - 永远不要依赖Timer处理异步操作,异步场景下
await才是可靠的等待方式。
内容的提问来源于stack exchange,提问作者Phyln

