Xamarin.Forms Shell应用iOS平台ToolbarItem触发ObjectDisposedException问题咨询
问题分析与解决方案
你遇到的这个Cannot access a disposed object. Object name: 'PrimaryToolbarItem'.异常确实是Xamarin.Forms在iOS平台处理Shell架构下ToolbarItem图标的已知问题,相关的缺陷记录在Xamarin.Forms的官方Issue仓库里有不少讨论。核心原因是iOS平台的ToolbarItem对应的原生控件UIBarButtonItem被提前释放后,Xamarin.Forms框架仍尝试去更新它的图标资源,从而触发了ObjectDisposedException。
问题触发的核心原因
在Shell的FlyoutItem对应的ShellContent页面场景下,iOS平台的ToolbarItem生命周期管理存在逻辑缺陷:
- 带有图标的ToolbarItem会被封装为
PrimaryToolbarItem,在页面导航切换、Shell状态变化过程中,这个对象可能被提前标记为Disposed - 后续框架的异步更新逻辑尝试访问这个已释放的对象的图标属性,就会抛出异常
- 仅使用Text属性时不会触发问题,是因为纯文本的ToolbarItem不会走复杂的图标资源加载与更新流程,避开了访问已释放对象的逻辑
你的临时方案可行,还有这些优化方向:
方案1:保留文本但清空iOS平台的图标
如果可以接受iOS平台仅显示ToolbarItem文本,不需要图标,可以修改代码避免清空整个ToolbarItems:
public HomePage() { InitializeComponent(); if (DeviceInfo.Platform == DevicePlatform.iOS) { foreach (var item in this.ToolbarItems) { item.IconImageSource = null; } } }
方案2:动态延迟初始化ToolbarItem
不在XAML中直接定义ToolbarItem,而是在页面的Appearing事件中动态添加,避开页面初始化时的生命周期冲突:
protected override void OnAppearing() { base.OnAppearing(); // 避免重复添加 if (ToolbarItems.Count == 0) { ToolbarItems.Add(new ToolbarItem { Name = "xicon", IconImageSource = ImageSource.FromResource("MobileApp.Resources.Images.x.png"), Text = "Saw X" }); // 同理添加yicon和zicon } }
方案3:升级Xamarin.Forms版本
这个缺陷在Xamarin.Forms的较新稳定版本(比如5.0.0.2401及以后)中已经被官方修复,如果你还在使用旧版本,升级到最新的稳定版可以从根源解决该问题。
总结
这个问题属于Xamarin.Forms iOS平台Shell架构下的已知生命周期管理缺陷,你当前的临时方案(清空iOS的ToolbarItems)是有效的,也可以根据实际需求选择上面的其他优化方案。
内容的提问来源于stack exchange,提问作者saramgsilva
相关产品推荐
相关产品推荐

