SwiftUI中使用Realm创建关联模型数组及数据遍历的方法
原有模型的核心适配问题
你当前写的模型定义无法被Realm正常持久化,核心原因是Realm不支持用原生Swift数组存储关联的Object类型,必须使用Realm专门提供的集合类型来维护对象间的关联关系,否则数据存储后会出现读取丢失、关联关系失效的问题。
正确的模型定义方案
按照你需要的“球队关联多个球员、可直接通过球队访问全部球员”的业务场景,修正后的模型代码如下:
import RealmSwift class Team: Object { @objc dynamic var teamName: String = "" // 使用Realm专属的List集合存储关联球员,替代原有的原生数组 let players = List<Player>() } class Player: Object { @objc dynamic var playerName: String = "" @objc dynamic var shirtNumber: Int = 0 // 可选字段:如果后续需要从球员侧反向查找所属球队,可以新增这个正向关联字段 @objc dynamic var belongTeam: Team? }
注意:
List类型不需要添加@objc dynamic修饰,它本身是Realm内置的带数据观察能力的托管类型,和原生数组的遍历、取值逻辑完全一致,上手门槛很低。
核心业务功能的实现逻辑
新建球队
所有写入Realm的操作都需要包裹在write事务闭包中,新建球队的示例代码:
// 全局初始化Realm实例(项目启动时初始化一次即可,不需要每次操作都新建) let defaultRealm = try! Realm() // 构造新的球队实例 let lakersTeam = Team() lakersTeam.teamName = "洛杉矶湖人" // 提交写入事务 try! defaultRealm.write { defaultRealm.add(lakersTeam) }
新建球员并分配到指定球队
拿到用户选定的目标球队实例后,直接把新球员加入球队的players列表即可完成关联,不需要额外操作:
// 从Realm中获取用户选中的目标球队(示例为通过队名查询) guard let targetTeam = defaultRealm.objects(Team.self).filter("teamName == %@", "洛杉矶湖人").first else { return } // 构造新球员实例 let newPlayer = Player() newPlayer.playerName = "勒布朗·詹姆斯" newPlayer.shirtNumber = 23 try! defaultRealm.write { // 直接把球员追加到球队的关联列表,Realm会自动维护对象间的关联关系 targetTeam.players.append(newPlayer) // 如果模型里加了反向关联字段,这里同步赋值保持双向关系一致 newPlayer.belongTeam = targetTeam }
多层遍历的访问逻辑
按照你需要的“遍历所有球队、再遍历每支球队下的关联球员”的需求,不需要手动把数据从Realm里取出来转成原生数组,Realm提供的懒加载集合可以直接遍历:
// 获取Realm中存储的所有球队,返回的是懒加载的Results类型,不会一次性加载全量数据进内存 let allStoredTeams = defaultRealm.objects(Team.self) // 外层循环遍历每一支球队 for singleTeam in allStoredTeams { print("当前球队:\(singleTeam.teamName)") // 内层循环遍历当前球队关联的全部球员 for singlePlayer in singleTeam.players { print("\t 球员:\(singlePlayer.playerName),球衣号码:\(singlePlayer.shirtNumber)") } }
入门提示:如果后续需要加筛选逻辑(比如只筛选名字包含“金州”的球队、或者只查球衣号大于10的球员),可以直接在对应的集合对象上调用
filter方法写查询条件,不需要手动循环遍历做匹配。
内容的提问来源于stack exchange,提问作者benpomeroy9
相关产品推荐
相关产品推荐

