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

iOS端MAUI应用操作导航栈后页面加载崩溃(空引用异常)求助

iOS端加载新页面时操作导航栈导致NullReferenceException崩溃

问题场景

导航栈初始包含Page1、Page2,从Page2跳转至Page3时,在Page3初始化阶段移除导航栈中的Page2,待Page3加载完成后应用崩溃,仅iOS端出现该问题。

代码实现

MainThread.InvokeOnMainThreadAsync(() =>
{
    while (pageElementType != endPageType)
    {
        if (pageElementType == startPageType)
        {
            removePageIndex = index + 1;
        }
        else if (removePageIndex > 0)
        {
            try
            {
                // 注释掉该行后,跳转至下一页后应用不会崩溃
                navService.RemovePage(navService.NavigationStack[removePageIndex]);

                index--;
            }
            catch (Exception ex)
            {
                // 记录异常
                Common.Log.Error($"{nameof(ManipulateNavStack)}", ex);
            }
        }

        index++;

        if (index < navService.NavigationStack.Count)
        {
            pageElementType = ((BaseViewModel)navService.NavigationStack[index].BindingContext).PageType;
        }
        else
        {
            break;
        }
    }
});

异常信息

Object reference not set to an instance of an object at Microsoft.Maui.Controls.Handlers.Compatibility.NavigationRenderer.ParentingViewController.WillMoveToParentViewController.
Full Path: System.NullReferenceException: Object reference not set to an instance of an object at Microsoft.Maui.Controls.Handlers.Compatibility.NavigationRenderer.ParentingViewController.WillMoveToParentViewController(UIViewController parent) at UIKit.UIApplication.UIApplicationMain(Int32 argc, String[] argv, IntPtr principalClassName, IntPtr delegateClassName) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/UIKit/UIApplication.cs:line 61 at UIKit.UIApplication.Main(String[] args, Type principalClass, Type delegateClass) in /Users/builder/azdo/_work/1/s/xamarin-macios/src/UIKit/UIApplication.cs:line 96 at xxxxx.Mobile.Program.Main(String[] args

已尝试在主线程执行移除操作,但问题依旧。

问题分析

该崩溃源于iOS导航控制器生命周期与MAUI导航栈操作不同步:Page3尚未完成入栈渲染时,就修改导航栈移除Page2,导致MAUI兼容性渲染器NavigationRenderer内部的ParentingViewController处理生命周期事件时,引用的页面已失效,触发空引用异常。同时原代码在遍历导航栈的同时修改栈结构,容易导致索引混乱,加剧引用失效问题。

解决方案

方案1:延迟操作至Page3完全加载后

不在Page3初始化阶段修改导航栈,而是在OnAppearing事件触发后执行移除逻辑,此时页面已完成入栈与渲染,生命周期状态稳定:

// 在Page3的代码中
protected override void OnAppearing()
{
    base.OnAppearing();
    MainThread.BeginInvokeOnMainThread(() =>
    {
        // 执行移除Page2的逻辑
        ManipulateNavStack();
    });
}

方案2:调整导航栈操作时机

先完成Page3的跳转,再执行移除操作,避免跳转过程中修改栈结构:

// 替代原有跳转+移除逻辑
await navService.PushAsync(page3);
// 跳转完成后移除Page2
MainThread.BeginInvokeOnMainThread(() =>
{
    var page2 = navService.NavigationStack.FirstOrDefault(p => p.GetType() == typeof(Page2));
    if (page2 != null)
    {
        navService.RemovePage(page2);
    }
});

方案3:批量移除避免遍历修改冲突

先收集所有需要移除的页面,再批量执行移除操作,避免遍历栈时修改栈结构导致的索引混乱:

MainThread.InvokeOnMainThreadAsync(() =>
{
    var pagesToRemove = new List<Page>();
    foreach (var page in navService.NavigationStack)
    {
        var vm = page.BindingContext as BaseViewModel;
        if (vm != null && vm.PageType == 目标移除页面类型)
        {
            pagesToRemove.Add(page);
        }
    }
    // 批量移除页面
    foreach (var page in pagesToRemove)
    {
        navService.RemovePage(page);
    }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 13:10:21