弹出模态框时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
相关产品推荐
相关产品推荐

