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

SwiftUI 子视图确认后调用父视图方法 报Segmentation Fault:11咨询

问题解答

技术上完全可以实现子视图获取用户确认后调用父视图对应方法,你遇到的Segmentation Fault:11错误是代码存在多处类型、逻辑错误导致,具体问题和修复方案如下:

错误原因

  • functionToPass类型定义错误:你声明的@State var functionToPass: ()是Void空类型,并非你需要的可执行闭包类型() -> Void,类型不匹配是触发崩溃的核心原因。
  • 赋值逻辑错误:onTapGesture中functionToPass = viewModel.deleteItem(name: item)是直接执行删除方法,把方法返回的Void值赋值给变量,而非把「删除指定item」的操作封装成闭包存储。
  • 视图层级不符合语法:SwiftUI要求body只能返回单个View类型,你直接把ForEach和SubStruct平级放置,未用容器包裹,会触发运行异常。
  • 子视图闭包逻辑错误:你传递给SubStruct的{functionToPass}只是在闭包内返回Void值,不会执行任何预期的删除操作。

修复后可运行代码

import SwiftUI

struct ContentView: View {
    var body: some View {
        MainStruct(viewModel: MyViewModel())
    }
}

struct MainStruct: View {
    @StateObject var viewModel: MyViewModel
    // 修正类型为闭包,默认赋值空闭包
    @State var functionToPass: () -> Void = {}
    
    // 注意:原数组存在重复的"test2",用\.self作为id会有识别冲突,实际开发建议用带唯一标识的模型
    let items = ["test1", "test2", "test3"]
    
    var body: some View {
        // 用VStack包裹多个平级子视图
        VStack(spacing: 20) {
            ForEach(items, id: \.self) { item in
                Text(item)
                    .onTapGesture {
                        // 把删除操作封装成闭包赋值,加弱引用避免循环引用
                        functionToPass = { [weak viewModel] in
                            viewModel?.deleteItem(name: item)
                        }
                    }
            }
            
            // 直接传递存储的闭包即可
            SubStruct(passedFunction: functionToPass)
        }
    }
    
    struct SubStruct: View {
        var passedFunction: () -> Void
        
        var body: some View {
            Button(action: {
                passedFunction()
            }, label: {
                Text("confirm deletion")
            })
        }
    }
    
}

class MyViewModel: ObservableObject {
    func deleteItem(name: String) {
        print("删除item:\(name)")
        ///deletion logic
    }
}

更推荐的实现方案

不需要额外存储闭包,直接存储当前选中的待删除item即可,逻辑更清晰不易出错:

struct MainStruct: View {
    @StateObject var viewModel: MyViewModel
    @State var selectedItem: String?
    let items = ["test1", "test2", "test3"]
    
    var body: some View {
        VStack(spacing: 20) {
            ForEach(items, id: \.self) { item in
                Text(item)
                    .onTapGesture {
                        selectedItem = item
                    }
            }
            
            Button("confirm deletion") {
                guard let selectedItem = selectedItem else { return }
                viewModel.deleteItem(name: selectedItem)
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 15:48:02