Ios 如何在域中设置自动递增键?
对于每个ChatData对象,我都有一个唯一的msgidIos 如何在域中设置自动递增键?,ios,realm,Ios,Realm,对于每个ChatData对象,我都有一个唯一的msgid @interface ChatData : RLMObject @property NSInteger msgid; .... @end 但每次创建新对象时,我都必须查询所有对象并获取最后一个msgid RLMArray *all = [[ChatData allObjects] arraySortedByProperty:@"msgid" ascending:YES]; ChatData *last = [all lastObject
@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;
是否有一种有效的方法来替换此实现?领域没有自动增量行为,因此您需要自己管理它。我鼓励你问自己一个关于你的数据的问题: 是否需要有连续的整数ID? 如果不是,那么一个唯一的字符串主键就足够了。然后您可以使用类似于
[[nsuid UUID]UUIDString]
的方法来生成唯一的字符串ID。这样做的好处是,这些UUID或多或少都保证是唯一的,即使在多线程场景中也是如此
如果是这样的话,将最后一个数字始终保留在内存中可能更有效,这样就不需要每次生成新ID时都进行查询。如果对象可能在多个线程中创建,请确保您的
nextPrimaryKey()
函数线程安全,否则它可能会生成相同的数字两次(或更多!)。Swift 2.0中的自动增量id域:
在类域中插入代码并使用对象写入
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])
})
您将在Swift中使用此代码作为自动增量主键:
var myvalue = realm.objects(ChatData).map{$0.id}.maxElement() ?? 0
myvalue = myvalue + 1
我在模型中使用了creationDate,因此我基于该日期创建了一个Unix时间戳,并将其用作对象的主键 在我的例子中,它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
}
}
这基本上就是jpsim的答案中所建议的,使用
UUID
生成唯一密钥。我们在插入之前进行查询以确保唯一性。这通常只会引起一个查询;在非常罕见的冲突情况下,它将继续运行,直到找到唯一的id。此解决方案是领域
类型的自然扩展,并且是继承自对象
的类的泛型。该类必须实现primaryKey
,并返回字符串
属性的名称
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)
}
}
扩展域{
func createAutoUnique(uType:T.type)->T{
guard let primaryKey=T.primaryKey()else{
fatalError(“createAutoUnique要求\(T.self)实现primaryKey()”)
}
变量id:String
现有风险值:T?=nil
重复{
id=UUID().UUIString
现有=对象(ofType:type,forPrimaryKey:id)
}while(现有!=nil)
let值=[
主密钥:id
]
返回创建(类型、值:值、更新:false)
}
}
在Realm中,您需要自行管理auto inc ID,因此有很多方法来管理它。下面是其中的一些
func incrementID() -> Int {
let realm = try! Realm()
return (realm.objects(Person.self).max(ofProperty: "id") as Int? ?? 0) + 1
}
每次添加记录时都调用此方法。是否有计划将自动增量行为添加到域中?是的,该功能即将推出,但我没有时间表。可以将其放入
+defaultPropertyValues
字典中,不是吗?我指的是[[nsuid UUID]UUIDString]
。要快速使用此nsuid().UUIDString
签出,如果有人关心领域自动增量功能,请访问anks bro:)又好又快!是的,多线程读写可能存在一些问题。这可能需要一些额外的进程。如果让retNext=realm.objects(rotero.self).sorted(byKeyPath:“id”).first?.id{这应该是最后一项,就像让retNext=realm.objects(Ordernew.self).sorted(byKeyPath:“id”).last?.id{我得到了这个错误“插入对象后无法更改主键”@Tofaani KaanudoApp因以下错误而终止:“插入对象后无法更改主键”。是否有其他方法更新主键?很棒的解决方案。效果很好。谢谢:)func nextId()->Int{return(realm?.objects(MyRealmObject.self)。map{$0.id}.max()??0)+1}