iOS UITextView数组清空后仍残留数据的问题排查求助
解决UITextView重置后残留幽灵视图的问题
嘿,这个坑我之前踩过!你遇到的问题核心很明确:你只是把存储UITextView的textViewArray清空了,但那些已经被添加到screenView上的旧UITextView,根本没从父视图的层级中移除——它们还被screenView强引用着,所以会一直留在界面上,和新创建的视图重叠,就出现了所谓的“幽灵图像”。
最直接的修复步骤
在你重置textViewArray为空之前,必须先遍历数组里的每个UITextView,把它们从父视图中移除:
// 先清理旧视图,再清空数组 for textView in textViewArray { textView.removeFromSuperview() } textViewArray = [] // 接下来再执行你原来的创建新UITextView的代码...
removeFromSuperview()方法会把视图从父视图的层级中剥离,同时系统会自动处理后续的内存释放(只要没有其他地方还强引用这些旧视图)。只清空数组的话,旧视图因为还被screenView持有,完全不会被销毁,自然会留在界面上。
更优的优化方案:复用视图而非销毁重建
每次都销毁重建UITextView其实有点浪费性能,尤其是当文本块数量变化不大的时候。你可以复用已有的UITextView,只更新它们的属性(文本、字体、frame等),这样既高效又能避免视图层级混乱:
topOfViewFrame = 0 textViewArray.removeAll() for (index, textBlock) in textBlocks.textBlocksArray.enumerated() { let textBlockHeight = CGFloat(textBlock.numberOfLines) * textBlock.blockFontSize let viewFrame = CGRect(x: 0, y: topOfViewFrame, width: textBoxWidth, height: textBlockHeight) let centerPoint = CGPoint(x: screenView.frame.width/2, y: topOfViewFrame + (textBlockHeight/2)) var textView: UITextView // 尝试复用已有的视图 if index < screenView.subviews.count, let existingTextView = screenView.subviews[index] as? UITextView { textView = existingTextView } else { // 没有可复用的,创建新视图 textView = UITextView(frame: viewFrame) screenView.addSubview(textView) } // 更新视图的所有属性 let viewFont = UIFont(name: "AvenirNextCondensed-Medium", size: textBlock.blockFontSize) textView.font = viewFont textView.text = textBlock.blockText textView = configureTextBlockView(textBoxView: textView, textBlock: textBlock) textView.frame = viewFrame textView.center = centerPoint textViewArray.append(textView) topOfViewFrame += textView.frame.height } // 如果新的文本块数量比原来的子视图少,移除多余的旧视图 while screenView.subviews.count > textBlocks.textBlocksArray.count { screenView.subviews.last?.removeFromSuperview() }
这种方式减少了视图创建销毁的开销,界面更新会更流畅,也从根源上避免了旧视图残留的问题。
额外检查点
如果按上面的方法做了还是有问题,那你需要排查一下:有没有其他地方(比如闭包、其他数组)还强引用着这些旧的UITextView?如果有,需要把那些引用也清理掉,确保系统能正常释放这些视图。
内容的提问来源于stack exchange,提问作者Gallaugher
相关产品推荐
相关产品推荐

