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
相关产品推荐
相关产品推荐

