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

Xamarin.iOS中Application.Current.Properties空异常及本地存储问题咨询

解决Xamarin.iOS中访问Application.Current.Properties时的空引用异常问题

嘿,我来帮你搞定这个空引用的坑!你遇到的这个情况在Xamarin.Forms跨平台开发里太常见了,核心原因其实很简单:你在Xamarin.iOS项目里访问Xamarin.Forms.Application.Current.Properties的时候,Application.Current还没完成初始化,处于null状态。

具体原因拆解

  • Application.Current是在Xamarin.Forms的App类实例化之后才会被赋值的。在iOS项目里,默认流程是先在AppDelegate的FinishedLaunching方法中初始化Forms,然后创建App实例。如果你的代码在这个流程之前执行(比如AppDelegate的构造函数里、提前加载的服务类里),那Application.Current肯定是null,碰它的Properties自然就炸了。
  • 如果你是在iOS原生代码(比如某个ViewController)里直接调用这段逻辑,但没确保Application.Current已经被正确初始化,也会触发空引用。

解决方案来了,分三种情况给你选

1. 确保在Application.Current初始化后再访问

调整iOS项目AppDelegate里的代码顺序,保证LoadApplication(new App())执行之后,再去碰Properties:

public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
    Xamarin.Forms.Forms.Init(); // 先初始化Forms框架
    LoadApplication(new App()); // 这一步才会创建App实例,给Application.Current赋值
    
    // 现在访问Properties就安全了
    if (Xamarin.Forms.Application.Current != null && 
        Xamarin.Forms.Application.Current.Properties.ContainsKey("isLogin"))
    {
        // 你的业务逻辑
    }
    
    return base.FinishedLaunching(app, options);
}

要是在其他类里访问,记得先加Application.Current的null判断,同时确保这个类是在LoadApplication之后才被调用的。

2. 用依赖服务封装本地存储(推荐!更优雅的跨平台方案)

直接在原生项目里硬怼Forms的Properties其实不是最佳实践,跨平台开发就得用跨平台的思路。定义一个统一的存储接口,各平台实现原生存储:

  • 先在Forms项目里定义接口:
public interface ILocalStorageService
{
    bool HasKey(string key);
    T GetValue<T>(string key);
    void SetValue<T>(string key, T value);
}
  • 然后在iOS项目里实现这个接口(用iOS原生的NSUserDefaults,比Forms的Properties更稳定):
[assembly: Dependency(typeof(LocalStorageService))]
namespace YourApp.iOS
{
    public class LocalStorageService : ILocalStorageService
    {
        private readonly NSUserDefaults _userDefaults;

        public LocalStorageService()
        {
            _userDefaults = NSUserDefaults.StandardUserDefaults;
        }

        public bool HasKey(string key)
        {
            return _userDefaults.ObjectForKey(new NSString(key)) != null;
        }

        public T GetValue<T>(string key)
        {
            var value = _userDefaults.ObjectForKey(new NSString(key));
            return value == null ? default : (T)Convert.ChangeType(value.ToString(), typeof(T));
        }

        public void SetValue<T>(string key, T value)
        {
            _userDefaults.SetString(value.ToString(), new NSString(key));
            _userDefaults.Synchronize();
        }
    }
}
  • 最后在Forms项目里通过DependencyService调用,不管哪个平台都能安全用:
var storageService = DependencyService.Get<ILocalStorageService>();
if (storageService.HasKey("isLogin"))
{
    var isLogin = storageService.GetValue<bool>("isLogin");
    // 你的业务逻辑
}

3. 直接在Forms的App类里处理存储逻辑

如果一定要用Forms的Properties,那就在App类的构造函数或者OnStart方法里操作,这里Application.Current肯定已经初始化完成了:

public partial class App : Application
{
    public App()
    {
        InitializeComponent();
        // 这里访问Properties绝对安全
        if (Properties.ContainsKey("isLogin"))
        {
            // 处理逻辑
        }
    }

    protected override void OnStart()
    {
        // 这里也可以放心用Properties
    }
}

总的来说,核心就是时机问题——Application.Current不是天生就有的,必须等Forms初始化+App实例加载完成才能用。用依赖服务封装原生存储不仅能避免这类空引用,还能让你的代码更符合跨平台开发的最佳实践。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:39:01