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
相关产品推荐
相关产品推荐

