领域将数据附加到类型列表< t> [英] Realm append data to a type List<t>

查看:118
本文介绍了领域将数据附加到类型列表< t>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试浏览数据并将其保存在我的模型中,但无论我做什么,我都会遇到以下错误:无法在写入事务之外改变持久化数组。。我究竟做错了什么?我将每场比赛追加到联赛但是它似乎不起作用?

I'm trying to go through data and save it in my model, however whatever i do i keep getting the following error: Can't mutate a persisted array outside of a write transaction.. What am i doing wrong? i'm appending each match to the league however it does not seem to work?

境界型号

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)
                    }
                }
        }
    }
}


推荐答案

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

Simplifying your code to show only the general structure helps to reveal the issue:

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.matches 。然后创建一个写入事务,并将联盟保存到Realm。从这一点来说,联盟不再是独立的,只能在写入事务中进行修改。在循环的下一次迭代中,您创建另一个匹配实例并尝试将其附加到 league.matches 。由于联盟是持久存在而且我们不在写入事务中,因此抛出。

This is the sequence of events: You start by creating a standalone, unpersisted League instance, league. For each match, you create a standalone, unpersisted Match instance and append it to league.matches. You then create a write transaction, and save league to the Realm. From this point, league is no longer standalone, and may only be modified within a write transaction. On the next iteration of the loop you create another Match instance and attempt to append it to league.matches. This throws since league is persisted and we're not in a write transaction.

这里的一个解决方案是重构代码,这样你只需将联盟保存到Realm一次,如下所示:

One solution here would be to restructure the code so you only save league to the Realm once, like so:

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)
}

这篇关于领域将数据附加到类型列表&lt; t&gt;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆