如何在Realm中设置自动递增键?

每个ChatData对象都有一个唯一的msgid。

@interface ChatData : RLMObject @property NSInteger msgid; .... @end 

但每次我创build一个新的对象,我不得不查询所有的对象,并得到最后一个msgid。

 RLMArray *all = [[ChatData allObjects] arraySortedByProperty:@"msgid" ascending:YES]; ChatData *last = [all lastObject]; ChatData *newData = [[ChataData alloc]init]; newData.msgid = last.msgid+1; 

有没有一个有效的方法来取代这个实现?

领域没有自动增量行为,所以你需要自己pipe理。 一个问题,我鼓励你问你自己的数据:

是否有必要有连续的,连续的整数ID?

如果不是,那么唯一的string主键可能就足够了。 然后你可以使用[[NSUUID UUID] UUIDString]来产生唯一的stringID。 关于这一点的好处是,即使在multithreading场景下,这些UUID或多或less地保证是唯一的。

如果是这样,那么始终将最后一个数字保存在内存中可能会更高效,因此每次生成新的ID时都不需要查询。 如果对象可能在多个线程中创build,请确保使nextPrimaryKey()函数是线程安全的,否则它可能会生成两次(或更多!)相同的数字。

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

您在Swift中使用此代码自动增量主键:

 var myvalue = realm.objects(ChatData).map{$0.id}.maxElement() ?? 0 myvalue = myvalue + 1 

我在我的模型中使用了creationDate,所以我创build了一个基于这个date的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 } } 

这实质上就是jpsim答案中的build议,使用UUID生成唯一键。 我们在插入之前查询,以确保唯一性。 这通常只会产生一个查询; 在非常罕见的碰撞情况下,它会一直持续到find一个唯一的ID。 这个解决scheme是Realmtypes的一个自然扩展,并且是从Objectinheritance的类的generics。 该类必须实现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) } } 

在Realm中,您需要自行pipe理自动识别ID,因此有很多方法可以进行pipe理。 下面是其中的一些。

  func incrementID() -> Int { let realm = try! Realm() return (realm.objects(Person.self).max(ofProperty: "id") as Int? ?? 0) + 1 } 

每次添加logging时都要调用这个方法。