我正在尝试遍历数据并将其保存在模型中,但是无论如何我都会收到以下错误:Can't mutate a persisted array outside of a write transaction.。我究竟做错了什么?我要将每场比赛都附加到联赛中,但是似乎不起作用?

领域模型

class League: Object {
    dynamic var id: Int = 0
    dynamic var name: String? = ""
    var matches = List<Match>()

    override class func primaryKey() -> String {
        return "id"
    }
}

class Match: Object {
    dynamic var matchId: Int = 0
    dynamic var date: NSDate?
    dynamic var homeName: String? = ""
    dynamic var awayName: String? = ""
    dynamic var awayScore: Int = 0
    dynamic var homeScore: Int = 0
    dynamic var leagueName: String? = ""
    dynamic var homeLogo: NSData?
    dynamic var awayLogo: NSData?
}

代码
    for (_, item) in result {
        if let leagueId = item["league"].int,
            let leagueName = item["name"].string,
            let allMatches = item["matches"].array {
                let league = League()
                league.name = leagueName
                league.id = leagueId

                for match in allMatches {
                    if let matchId = match["matchId"].int,
                        let tournament = match["tournament"].string,
                        let homeTeam = match["homeName"].string,
                        let awayTeam = match["awayName"].string,
                        let homeScore = match["homeScore"].int,
                        let awayScore = match["awayScore"].int,
                        let homeLogo = match["homeLogo"].string,
                        let awayLogo = match["awayLogo"].string,
                        let date = match["date"].string {
                            if let awayLogoUrl = NSURL(string: awayLogo),
                                let homeLogoUrl = NSURL(string: homeLogo) {
                                    if let awayLogoData = NSData(contentsOfURL: awayLogoUrl),
                                        let homeLogoData = NSData(contentsOfURL: homeLogoUrl) {
                                            let matchObject = Match()
                                            matchObject.matchId = matchId
                                            matchObject.leagueName = tournament
                                            matchObject.homeName = homeTeam
                                            matchObject.awayName = awayTeam
                                            matchObject.homeScore = homeScore
                                            matchObject.awayScore = awayScore
                                            matchObject.homeLogo = homeLogoData
                                            matchObject.awayLogo = awayLogoData

                                            let formatter = NSDateFormatter()
                                            formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
                                            formatter.timeZone = NSTimeZone(abbreviation: "CET")
                                            matchObject.date = formatter.dateFromString(date)!

                                            league.matches.append(matchObject)
                                    }
                            }
                    }

                    print(league)

                    try! realm.write {
                        realm.add(league, update: true)
                    }
                }
        }
    }
}

最佳答案

简化代码以仅显示一般结构有助于揭示问题:

let league = League()
league.name = leagueName
league.id = leagueId

for match in allMatches {
    if … {
        let matchObject = Match()
        …

        league.matches.append(matchObject)
    }

    print(league)

    try! realm.write {
        realm.add(league, update: true)
    }
}

这是事件的顺序:首先创建一个独立的,未持久的League实例league。对于每个匹配项,您将创建一个独立的,未持久的Match实例,并将其附加到league.matches。然后,您创建一个写事务,并将league保存到Realm。从这一点来看,league不再是独立的,只能在写事务中进行修改。在循环的下一次迭代中,您将创建另一个Match实例,并尝试将其附加到league.matches。因为league被保留并且我们不在写事务中,所以抛出该错误。

此处的一种解决方案是重组代码,因此您只需将league保存到Realm一次,就像这样:
let league = League()
league.name = leagueName
league.id = leagueId

for match in allMatches {
    if … {
        let matchObject = Match()
        …

        league.matches.append(matchObject)
    }
}

print(league)

try! realm.write {
    realm.add(league, update: true)
}

09-27 20:50