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

SwiftUI键盘扩展应用堆内存阶梯式上涨问题求助

解决键盘扩展内存阶梯式上涨问题

问题根源

你的键盘扩展每次打开时内存持续上涨,核心原因是:

  1. 重复创建视图容器:KeyboardViewController的viewDidLoad方法在键盘每次激活时可能被触发(iOS键盘扩展的生命周期特性),而你在该方法内每次都会新建UIHostingController实例并添加到视图层级,旧实例因被视图强引用无法释放,导致内存堆积。
  2. 不必要的实例属性: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 17:39:59