为什么领域列表包含相同的元素而不是不同的元素?
如下图所示,有两个relam-objects(UndoMemoryNameEntry和NameEntry)。第一个包含8个元素的列表。列表的元素类型是NameEntry!
类型
我的上一个NameEntry对象是用currentScorePlayer = 1和currentScoreMe = 15编写的,如下图所示:
UndoMemoryNameEntry中的列表正确插入了最后一个NameEntry对象。你会发现插入代码进一步向下...... 但现在问题是:为什么所有现有的list-elements都改为最新的插入元素????正如您在下图中所看到的,遗憾的是,所有元素都与最后添加的元素相同 - 为什么??????
如果我将NameEntry更改为以下内容:
在index = 0处插入列表,然后List更改为:
为什么所有的元素都改变了?而不只是插入一个???感谢您的帮助!
我的两个领域对象是:
class NameEntry: Object {
dynamic var playerName = ""
dynamic var isMyAdversary: Bool = false
dynamic var currentScorePlayer: Int = 0
dynamic var currentScoreMe: Int = 0
}
和列表:
class UndoMemoryNameEntry: Object {
dynamic var undoPlayerName = ""
let NameEntryList = List<NameEntry>()
}
以下代码创建了Realm-List:
// query rlm for existing object (with name adversary
let undoPredicate = NSPredicate(format: "undoPlayerName == %@", adversaryName)
let undoPlayerName = rlm.objects(UndoMemoryNameEntry).sorted("undoPlayerName", ascending: true).filter(undoPredicate)
// if undoPlayerName object does not exist - then create it!
if (undoPlayerName.count < 1) {
rlm.beginWrite()
let undoEntry = UndoMemoryNameEntry()
undoEntry.undoPlayerName = adversaryName
rlm.add(undoEntry)
rlm.commitWrite()
}
以下代码在列表中添加&#34; NameEntry&#34; -Element:
let undoPredicate = NSPredicate(format: "undoPlayerName == %@", plaNameLab)
let undoPlayerName = rlm.objects(UndoMemoryNameEntry).sorted("undoPlayerName", ascending: true).filter(undoPredicate)
if (undoPlayerName.count == 1) {
rlm.beginWrite()
println(entry)
var undoEntry = undoPlayerName[0] as UndoMemoryNameEntry
undoEntry.NameEntryList.insert(entry, atIndex: 0)
rlm.commitWrite()
}
上述代码异常完美 - 除了realm-List总是将其所有元素更改为刚刚插入的元素。
答案 0 :(得分:0)
我终于找到了解决方案:
首先按如下方式重新排列两个领域对象:
class NameEntry: Object {
dynamic var playerName = ""
dynamic var currentScorePlayer: Int = 0
dynamic var currentScoreMe: Int = 0
// the undo-list is better placed in the first object...
let undoEntryList = List<UndoMemoryNameEntry>()
override static func primaryKey() -> String? {
return "playerName"
}
}
class UndoMemoryNameEntry: Object {
dynamic var undoPlayerName = ""
dynamic var currentScorePlayer: Int = 0
dynamic var currentScoreMe: Int = 0
// no primary key here since the undoEntry will have several items with the same undoPlayerName
}
然后在List中添加“NameEntry”-Element:
let predicate = NSPredicate(format: "playerName == %@", plaNameLab)
let playerName = rlm.objects(NameEntry).sorted("playerName", ascending: true).filter(predicate)
if (playerName.count == 1) {
rlm.beginWrite()
var entry = playerName[0] as NameEntry
// you need to create a new list object first !!!!!!!!!!!!
// ...in my initial example, this creation was missing !!!!!!
var siblingEntry = UndoMemoryNameEntry()
siblingEntry.undoPlayerName = plaNameLab
siblingEntry.currentScorePlayer = entry.currentScorePlayer
siblingEntry.currentScoreMe = entry.currentScoreMe
// insert new list-element
entry.undoEntryList.insert(siblingEntry, atIndex: 0)
// alternatively choose append if you want to add the element at the end of the list
entry.undoEntryList.append(siblingEntry)
// or choose the "ringbuffer-solution" given in the add-on below if you want to restrict the number of list-elements to ringbuffer-size !
// ...
rlm.commitWrite()
}
加载项:如果要创建仅具有有限数量列表元素的环形缓冲区:
// create ringbuffer of 20 elements (20th element will be newest)
let ringBufferSize = 20
let undoPredicate = NSPredicate(format: "undoPlayerName == %@", plaNameLab)
if (entry.undoEntryList.filter(undoPredicate).sorted("undoPlayerName").count < ringBufferSize) {
entry.undoEntryList.append(siblingEntry)
}
else {
// entry.undoEntryList.replace(ringBufferSize-1, object: siblingEntry)
entry.undoEntryList.removeAtIndex(ringBufferSize-1)
entry.undoEntryList.append(siblingEntry)
for index in 0..<ringBufferSize-1 {
let tempEntry1 = rlm.objects(UndoMemoryNameEntry).filter(undoPredicate).sorted("undoPlayerName")[index] as UndoMemoryNameEntry
let tempEntry2 = rlm.objects(UndoMemoryNameEntry).filter(undoPredicate).sorted("undoPlayerName")[index+1] as UndoMemoryNameEntry
tempEntry1.currentScorePlayer = tempEntry2.currentScorePlayer
tempEntry1.currentScoreMe = tempEntry2.currentScoreMe
}
let tempEntry = rlm.objects(UndoMemoryNameEntry).filter(undoPredicate).sorted("undoPlayerName")[ringBufferSize-1] as UndoMemoryNameEntry
rlm.delete(tempEntry)
}