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

解决SwiftUI View与UIHostingController中'self'在super.init前调用的错误

解决SwiftUI调用UIKit关闭方法时的self used before super.init call错误

错误原因

在FlashcardHostingController的required init?(coder:)方法中,你试图在调用super.init之前捕获self来创建closeAction闭包。但Swift的初始化规则要求:必须先完成父类的初始化(即调用super.init),才能访问self,此时self的内存还未完全初始化,因此编译器报错。

解决方案

我们可以先创建一个占位的closeAction完成rootView的初始化,待super.init执行完成(self初始化完成)后,再替换为真正的关闭逻辑。修改后的代码如下:

struct FlashcardView: View {
    var closeAction: () -> Void
    
    var body: some View {
        NavigationView {
            Text("This is the main content")
                .navigationTitle("Your Title")
                .toolbar {
                    ToolbarItem(placement: .navigationBarTrailing) {
                        Button(action: closeAction) {
                            Image(systemName: "xmark")
                                .foregroundColor(.blue)
                        }
                    }
                }
        }
    }
}

class FlashcardHostingController: UIHostingController<FlashcardView> {
    required init?(coder: NSCoder) {
        // 先创建带空闭包的rootView,满足初始化要求
        let rootView = FlashcardView(closeAction: {})
        super.init(coder: coder, rootView: rootView)
        
        // 此时self已完成初始化,安全设置真正的closeAction
        self.rootView.closeAction = { [weak self] in
            self?.dismiss(animated: true, completion: nil)
        }
    }
}

说明

  • 先通过空闭包初始化rootView,确保能顺利调用super.init完成父类初始化流程。
  • super.init执行后,self的内存已完全分配,此时捕获[weak self]是合法的,既避免了循环引用,也能正确调用UIKit的dismiss方法。
  • 优化了SwiftUI按钮的action写法,直接传入closeAction即可,无需额外嵌套闭包。

内容的提问来源于stack exchange,提问作者Cheok Yan Cheng

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 01:56:03