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

弹出模态框时iOS自定义Entry渲染器出现NullReference异常求助

解决iOS自定义Entry渲染器在PopModalAsync时的空引用异常

这个问题的核心原因是你在自定义渲染器中订阅了Entry的Focused和Unfocused事件,但没有在元素被销毁时取消这些订阅,同时在事件触发时没有检查Control或Element是否还处于有效状态。当你使用await Navigation.PopModalAsync(true)时,页面会被完整销毁,此时之前订阅的事件可能仍然被触发,而此时Control或Element已经变为null,从而导致空引用异常。去掉await只是侥幸避开了空值触发时机,并不是正确的解决方式。

下面是修复后的完整渲染器代码,我标注了关键改进点:

public class BorderColorChange : EntryRenderer
{
    protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
    {
        base.OnElementChanged(e);

        // 移除旧元素的事件订阅,避免内存泄漏和空引用
        if (e.OldElement != null)
        {
            e.OldElement.Focused -= OnEntryFocused;
            e.OldElement.Unfocused -= OnEntryUnfocused;
        }

        if (e.NewElement != null && Control != null)
        {
            // 初始化基础样式
            Control.Layer.BorderWidth = 1;
            Control.Layer.CornerRadius = 4;
            // 设置初始边框颜色
            Control.Layer.BorderColor = UIColor.LightGray.CGColor;

            // 订阅新元素的事件
            e.NewElement.Focused += OnEntryFocused;
            e.NewElement.Unfocused += OnEntryUnfocused;
        }
    }

    private void OnEntryFocused(object sender, FocusEventArgs e)
    {
        // 触发事件前先检查Control是否有效
        if (Control != null)
        {
            Control.Layer.BorderColor = UIColor.FromRGB(3, 169, 244).CGColor;
        }
    }

    private void OnEntryUnfocused(object sender, FocusEventArgs e)
    {
        // 同样检查Control状态,避免空引用
        if (Control != null)
        {
            Control.Layer.BorderColor = UIColor.LightGray.CGColor;
        }
    }

    protected override void Dispose(bool disposing)
    {
        // 渲染器销毁时,彻底移除事件订阅并清理资源
        if (disposing && Element != null)
        {
            Element.Focused -= OnEntryFocused;
            Element.Unfocused -= OnEntryUnfocused;
        }

        base.Dispose(disposing);
    }
}

关键改进说明:

  • 取消旧元素事件订阅:在OnElementChanged中处理e.OldElement,移除之前绑定的事件,防止旧元素销毁后事件仍被触发。
  • 拆分事件处理方法:把事件逻辑抽成独立方法,方便订阅和取消操作,代码可读性也更强。
  • 事件触发时检查Control状态:每次事件触发前先判断Control是否为null,从根源避免空引用。
  • 重写Dispose方法:在渲染器生命周期结束时,再次确认移除事件订阅,彻底清理资源,防止内存泄漏和后续异常。

这样修改后,无论你是否使用await调用PopModalAsync,渲染器都会正确处理元素的生命周期,不会再出现空引用异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:30:11