SwiftUI FetchRequest用ObservedObject数据报错:初始化器先于self可用
解决CoreData关联成员FetchRequest初始化错误
错误原因
你编写的代码中,@FetchRequest作为属性初始化时,实例成员group还未完成初始化(Swift规定属性初始化器会在self实例创建前执行),因此无法直接在NSPredicate中引用group,触发报错:
Cannot use instance member 'group' within property initializer; property initializers run before 'self' is available
两种解决方案
方案一:利用CoreData已有的关联关系(最简实现)
既然Group与GroupMember已通过members(正向关联)和group(反向关联)建立绑定,直接通过group.members即可获取所有关联成员,无需额外编写FetchRequest:
struct GroupDetailView: View { @ObservedObject var group: Group // 对关联成员按firstName_排序 private var sortedMembers: [GroupMember] { (group.members as? Set<GroupMember>)?.sorted { $0.firstName_ ?? "" < $1.firstName_ ?? "" } ?? [] } var body: some View { List(sortedMembers) { member in Text(member.firstName_ ?? "Unknown") } } }
方案二:动态初始化FetchRequest
若必须使用@FetchRequest,可通过构造方法初始化,避开属性初始化阶段self不可用的限制:
struct GroupDetailView: View { @ObservedObject var group: Group private var members: FetchRequest<GroupMember> private var results: FetchedResults<GroupMember> { members.wrappedValue } init(group: Group) { self.group = group // 在构造方法中初始化FetchRequest,此时group已完成初始化 members = FetchRequest( sortDescriptors: [NSSortDescriptor(keyPath: \GroupMember.firstName_, ascending: true)], predicate: NSPredicate(format: "group == %@", group), animation: .default ) } var body: some View { List(results) { member in Text(member.firstName_ ?? "Unknown") } } }
补充说明
- 方案一借助CoreData自动维护的关联集合,代码更简洁,且能自动响应数据变更(因
group标记为@ObservedObject)。 - 方案二更适合需要复杂过滤逻辑的场景,通过构造方法初始化FetchRequest解决了属性初始化阶段的限制。
内容的提问来源于stack exchange,提问作者hfs23
相关产品推荐
相关产品推荐

