SwiftUI键盘扩展应用堆内存阶梯式上涨问题求助
解决键盘扩展内存阶梯式上涨问题
问题根源
你的键盘扩展每次打开时内存持续上涨,核心原因是:
- 重复创建视图容器:
KeyboardViewController的viewDidLoad方法在键盘每次激活时可能被触发(iOS键盘扩展的生命周期特性),而你在该方法内每次都会新建UIHostingController实例并添加到视图层级,旧实例因被视图强引用无法释放,导致内存堆积。 - 不必要的实例属性:
AnimalKeyboardView中的animalList和column是非静态属性,每个视图实例都会创建一份副本,造成额外内存消耗。
解决方案
1. 持久持有UIHostingController,避免重复创建
修改KeyboardViewController,将UIHostingController声明为实例属性,确保只初始化一次:
class KeyboardViewController: UIInputViewController { // 持有UIHostingController实例,防止重复创建 private var hostingController: UIHostingController<AnimalKeyboardView>? override func viewDidLoad() { super.viewDidLoad() // 已初始化过则直接返回,避免重复创建视图 guard hostingController == nil else { return } let keyboardView = AnimalKeyboardView { [weak self] text in guard let self else { return } self.textDocumentProxy.insertText(text) } hostingController = UIHostingController(rootView: keyboardView) guard let animalKeyboardView = hostingController?.view else { return } animalKeyboardView.translatesAutoresizingMaskIntoConstraints = false addChild(hostingController!) view.addSubview(animalKeyboardView) hostingController?.didMove(toParent: self) NSLayoutConstraint.activate([ animalKeyboardView.leftAnchor.constraint(equalTo: view.leftAnchor), animalKeyboardView.topAnchor.constraint(equalTo: view.topAnchor), animalKeyboardView.rightAnchor.constraint(equalTo: view.rightAnchor), animalKeyboardView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) } }
2. 优化SwiftUI视图的静态资源
将AnimalKeyboardView中的固定资源改为静态属性,让所有实例共享一份数据:
struct AnimalKeyboardView: View { var insertText: (String) -> Void // 静态属性,全局共享,避免重复创建 private static let animalList = ["🐱", "🐷", "🦫", "🦭", "🐼", "🐮", "🐰", "🐭", "🐘", "🐹", "🦊", "🐬"] private static let column = GridItem.init(.adaptive(minimum: 56, maximum: 56), spacing: 32) var body: some View { VStack(spacing: 24) { LazyVGrid(columns: [Self.column], spacing: 24, content: { ForEach(Self.animalList, id: \.self) { animal in Button(action: { insertText(animal) }, label: { Text(animal) .font(.system(size: 32)) .padding(.all, 8) .background( RoundedRectangle(cornerRadius: 8) .fill(.white.opacity(0.8)) ) }) } }) } .padding(.top, 32) .padding(.bottom, 16) .frame(height: 300) .frame(maxWidth: .infinity) } }
验证效果
修改后,每次打开键盘时不会再重复创建视图容器和静态资源,内存将保持稳定,不会出现阶梯式上涨的情况。
内容的提问来源于stack exchange,提问作者Asim Roy
相关产品推荐
相关产品推荐

