2

我正在尝试计算我的列表中有多少张卡片是相等的,并用计数更新新的数量属性

例如:

newObject!["list"] = [CardObject1, CardObject2, CardObject2, CardObject2, CardObject3, CardObject3]

分配到临时列表

var tempList = List()

CardObject1(将数量属性更新为 1)
CardObject2(将数量属性更新为 3)
CardObject3(将数量属性更新为 2)

tempList = [CardObject1,CardObject2,CardObject3]

分配回 newObject!["list"] 更新/迁移的列表

新对象![“列表”] = 新列表

newList.index(of: card)处崩溃

* 由于未捕获的异常“RLMException”而终止应用程序,原因:“对象类型“CardDTO”与 RLMArray 类型“DynamicObject”不匹配。*首先抛出调用栈:

信息:

甲板DTO.swift

class DeckDTO: Object {
dynamic var id = NSUUID().uuidString
dynamic var name = ""
var list = List<CardDTO>()

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

CardDTO.swift

class CardDTO: Object, Mappable {

// Other properties
dynamic var id = NSUUID().uuidString
dynamic var quantity: Int = 1
// Other properties

 required convenience public init?(map: Map) {
    self.init()
    mapping(map: map)
 }

 func mapping(map: Map) {
    //Map all my properties
 }

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

我正在尝试什么

if oldSchemaVersion < 2 {
  migration.enumerateObjects(ofType: CardDTO.className()) { oldObject, newObject in
    newObject!["quantity"] = 1
  }

  migration.enumerateObjects(ofType: DeckDTO.className()) { oldObject, newObject in
    var newList = List<DynamicObject>()
    let oldList = newObject!["list"] as! List<DynamicObject>
    for card in oldList {
        if let i = newList.index(of: card), i >= 0 {
            newList[i] = (newList[i] as! CardDTO).quantity += 1 //some how do quantity++
            print("increment quantity")
        } else {
            newList.append(card)
        }
    }
    newObject!["list"] = newList
  }
}
4

1 回答 1

1

领域迁移块(及其动态 API)并不适合您的特定用例。既index(of:)不能也append()不能与动态对象正确使用。

我对解决此问题的建议是quantity在迁移块中简单地将属性设置为 1,然后设置一个布尔标志,指示您需要执行卡组更新。然后,在您做任何其他事情之前(可能在 中application(_: didFinishLaunchingWithOptions:)),打开 Realm 并检查该标志。如果设置了该标志,您就可以打开 Realm 并使用普通的 Realm API 执行迁移。

这是一些示例代码:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    // Get the configuration and set the migration block on it
    var config = Realm.Configuration.defaultConfiguration
    config.schemaVersion = 2
    var needsMigrationToV2 = false

    config.migrationBlock = { migration, oldSchemaVersion in
        if oldSchemaVersion < 2 {
            migration.enumerateObjects(ofType: CardDTO.className()) { oldObject, newObject in
                newObject!["quantity"] = 1
            }
            needsMigrationToV2 = true
        }
    }
    let realm = try! Realm(configuration: config)
    // Run the rest of the migration using the typed API
    if needsMigrationToV2 {
        let allDecks = realm.objects(DeckDTO.self)
        try! realm.write {
            for deck in allDecks {
                var uniqueCards : [CardDTO] = []
                for card in deck.list {
                    if uniqueCards.contains(card) {
                        card.quantity += 1
                    } else {
                        uniqueCards.append(card)
                    }
                }
                deck.list.removeAll()
                deck.list.append(objectsIn: uniqueCards)
            }
        }
    }
    return true
}

还有一点需要注意的是,List<T>属性应该声明为let,而不是var,因为重新分配给List<T>属性是错误的。

于 2017-02-27T22:53:58.830 回答