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

使用TextKit 1替换UITextView的NSLayoutManager时崩溃求助

问题描述

在Storyboard中创建了采用TextKit 1的UITextView,尝试替换其内部的NSLayoutManager,但调用该文本视图的.sizeThatFits()(或其他布局相关方法)时,触发未捕获异常:

*** -[NSLayoutManager glyphRangeForTextContainer:]: given container does not appear in the list of containers for this NSLayoutManager.

替换布局管理器的代码如下:

let layoutManager = MyLayoutManager()
layoutManager.textStorage = self.textStorage        
layoutManager.addTextContainer(self.textContainer)      
self.textContainer.replaceLayoutManager(layoutManager)
// etc.

尝试在initWithCoder和awakeFromNib中执行上述操作,且确认布局管理器的textContainers数组确实包含当前textContainer。即使使用原生NSLayoutManager而非自定义子类,崩溃依然发生。

通过堆栈跟踪发现崩溃触发自TextKit 1的私有方法,且进入.sizeThatFits()前,layoutManager.textContainers.contains(self.textContainer)返回true。自定义布局管理器的glyphRangeForTextContainer:方法并未被私有方法调用,怀疑私有方法仍在引用内存中旧布局管理器的残留。该问题在TextKit 1的空项目中也可复现,暂无法确定是系统Bug还是自身操作错误。

解决方案

问题出在TextKit组件的关联顺序和旧布局管理器的解除逻辑上,UITextView初始化时会自动创建一套默认的NSTextStorage、NSLayoutManager、NSTextContainer关联关系,直接替换时可能未彻底切断旧关联,导致私有方法仍引用旧布局管理器。

正确的替换步骤应该是:

  1. 先解除旧布局管理器与textStorage、textContainer的关联
  2. 再将新布局管理器与textStorage、textContainer建立关联
  3. 最后更新UITextView的layoutManager属性

修改后的代码示例:

override func awakeFromNib() {
    super.awakeFromNib()
    
    // 获取旧布局管理器并解除关联
    let oldLayoutManager = self.layoutManager
    oldLayoutManager?.removeTextContainer(self.textContainer)
    self.textStorage?.removeLayoutManager(oldLayoutManager)
    
    // 创建并配置新布局管理器
    let newLayoutManager = MyLayoutManager()
    self.textStorage?.addLayoutManager(newLayoutManager)
    newLayoutManager.addTextContainer(self.textContainer)
    
    // 更新UITextView的布局管理器引用
    self.layoutManager = newLayoutManager
}

关键说明

  • 必须先移除旧布局管理器的关联:TextKit的三个组件是双向绑定的,仅替换一侧会导致残留引用,私有方法可能仍通过旧关联访问错误的布局管理器
  • 优先使用textStorage.addLayoutManager()而非直接设置layoutManager.textStorage:前者会正确处理双向关联,后者可能遗漏部分绑定逻辑
  • 在awakeFromNib中执行替换:此时UITextView的所有组件已完成初始化,避免在initWithCoder中操作时组件未完全创建导致的异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 04:09:27