我为每个ChatData对象都有一个唯一的msgid。
@interface ChatData : RLMObject
@property NSInteger msgid;
....
@end
但每次我创建一个新对象时,我都要查询所有对象并获取最后一个msgid。
RLMArray *all = [[ChatData allObjects] arraySortedByProperty:@"msgid" ascending:YES];
ChatData *last = [all lastObject];
ChatData *newData = [[ChataData alloc]init];
newData.msgid = last.msgid+1;
是否有一种有效的方法来替换此实现?
答案 0 :(得分:52)
Realm没有自动增量行为,因此您需要自己管理。一个问题我鼓励您问问自己您的数据:
是否需要连续的,连续的整数ID?
如果没有,那么唯一的字符串主键可能就足够了。然后,您可以使用[[NSUUID UUID] UUIDString]
之类的内容生成唯一的字符串ID。关于这一点的好处是,即使在多线程场景中,这些UUID也或多或少地保证是唯一的。
如果是这样,始终将最后一个数字保留在内存中可能更有效,因此每次生成新ID时都不需要查询。如果可能在多个线程中创建对象,请确保使nextPrimaryKey()
函数具有线程安全性,否则它可能会生成相同的数字两次(或更多!)。
答案 1 :(得分:11)
您在Swift中使用此代码作为自动增量主键:
var myvalue = realm.objects(ChatData).map{$0.id}.maxElement() ?? 0
myvalue = myvalue + 1
答案 2 :(得分:10)
Swift 2.0中的Autoincrement id Realm: 在类领域插入代码和对象写入使用
import Foundation
import RealmSwift
class Roteiro: Object {
dynamic var id = 0
dynamic var Titulo = ""
dynamic var Observacao = ""
dynamic var status = false
dynamic var cadastrado_dt = NSDate()
override static func primaryKey() -> String? {
return "id"
}
//Incrementa ID
func IncrementaID() -> Int{
let realm = try! Realm()
if let retNext = realm.objects(Roteiro.self).sorted(byKeyPath: "id").first?.id {
return retNext + 1
}else{
return 1
}
}
在文件写入中使用:
let Roteiro_Add = Roteiro()
//increment auto id
Roteiro_Add.id = Roteiro_Add.IncrementaID()
Roteiro_Add.Titulo = TituloDest
Roteiro_Add.Observacao = Observacao
Roteiro_Add.status = false
let realm = try! Realm()
try! realm.write({ () -> Void in
realm.add([Roteiro_Add])
})
答案 3 :(得分:2)
在Realm中,您需要自行管理auto-inc ID,因此有很多方法可以管理它。以下是其中一些。
func incrementID() -> Int {
let realm = try! Realm()
return (realm.objects(Person.self).max(ofProperty: "id") as Int? ?? 0) + 1
}
每次添加记录时都会调用此方法。
答案 4 :(得分:0)
我在模型中使用了creationDate,所以我根据这个日期创建了一个 Unix timeStamp ,并将它用作我对象的primaryKey。
99.99%保证在我的情况下是唯一的 (因为时间戳精确到秒),但它可能取决于您的使用案例。 它不如UUID强大,但在很多情况下它足够了。
extension NSDate {
/** Returns a NSDate instance from a time stamp */
convenience init(timeStamp: Double) {
self.init(timeIntervalSince1970: timeStamp)
}
}
extension Double {
/** Returns a timeStamp from a NSDate instance */
static func timeStampFromDate(date: NSDate) -> Double {
return date.timeIntervalSince1970
}
}
答案 5 :(得分:0)
这基本上是在jpsim的回答中建议的,使用UUID
生成唯一键。我们在插入之前进行查询以确保唯一性。这通常只会产生一个查询;在非常罕见的碰撞情况下,它会一直持续到找到唯一的ID。此解决方案是Realm
类型的自然扩展,对于继承自Object
的类是通用的。该类必须实现primaryKey
并返回String
属性的名称。
extension Realm {
func createAutoUnique<T: Object>(_ type: T.Type) -> T {
guard let primaryKey = T.primaryKey() else {
fatalError("createAutoUnique requires that \(T.self) implements primaryKey()")
}
var id: String
var existing: T? = nil
repeat {
id = UUID().uuidString
existing = object(ofType: type, forPrimaryKey: id)
} while (existing != nil)
let value = [
primaryKey: id
]
return create(type, value: value, update: false)
}
}