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

.NET for iOS中RichTextView构造函数重复调用问题排查

问题本质与解决方案

核心原因

你遇到的问题源于**RichTextView(NativeHandle)构造函数的实现不符合.NET for iOS的对象绑定规则**:

  1. 在.NET for iOS中,NativeHandle构造函数的设计目的是包装已存在的原生iOS对象,而非创建新对象。当你设置SelectedRange触发原生API调用时,运行时会检查托管对象与原生对象的绑定关系,若发现映射异常,就会尝试通过该构造函数重新生成托管包装。
  2. 你的所有构造函数(包括NativeHandle版本)都调用了Initialize方法,这会在每次包装原生对象时重新配置委托、KeyCommands等,直接覆盖之前已设置好的状态,造成“重置”现象。
  3. 该问题未在Xamarin.iOS中出现,是因为.NET 7的.NET for iOS对托管-原生对象的映射检查更严格,触发了之前未暴露的构造函数实现缺陷。

正确的构造函数实现方式

你需要拆分初始化逻辑,区分创建新对象和包装已有原生对象两种场景:

public class RichTextView : UITextView
{
    // 创建新对象时使用的无参构造函数
    public RichTextView() : base()
    {
        Initialize();
    }

    // 从NIB/Storyboard加载时的构造函数
    public RichTextView(NSCoder coder) : base(coder)
    {
        Initialize();
    }

    // 包装已有原生对象的NativeHandle构造函数
    public RichTextView(NativeHandle handle) : base(handle)
    {
        // 此处禁止调用Initialize!
        // 原生对象已存在,需保留其现有状态
    }

    // 仅针对新对象的初始化逻辑
    private void Initialize()
    {
        // 配置委托、KeyCommands等初始化操作
        this.Delegate = new RichTextViewDelegate();
        this.KeyCommands = new UIKeyCommand[] { ... };
        // 其他新对象所需的初始化步骤
    }
}

关于“空实现”的说明

NativeHandle构造函数的空实现并非hack,而是符合其设计意图:它仅负责建立托管对象与原生对象的绑定,无需修改原生对象状态——此时原生对象已是完整实例(比如你之前通过无参构造函数创建并配置好的实例),重新初始化会破坏已有状态。

额外排查点

  • 检查加载对象的函数,确认是否在序列化/反序列化过程中错误重建了托管对象,导致运行时触发重新绑定。
  • 确保RichTextView的所有状态变更都同步到原生对象,避免运行时判定托管-原生对象状态不一致,触发重新绑定逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 03:45:18