39

我对每个 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;

有没有一种有效的方法来替换这个实现?

4

6 回答 6

57

Realm 没有自动增量行为,因此您需要自己管理。我鼓励你问自己关于你的数据的一个问题:

是否需要有连续的、连续的、整数 ID?

如果没有,那么唯一的字符串主键可能就足够了。然后你可以使用类似的东西[[NSUUID UUID] UUIDString]来生成唯一的字符串 ID。这样做的好处是这些 UUID 或多或少保证是唯一的,即使在多线程场景中也是如此。

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

于 2014-10-08T13:03:43.177 回答
16

您正在将此代码用于 Swift 中的自动增量主键:

var myvalue = realm.objects(ChatData).map{$0.id}.maxElement() ?? 0
myvalue = myvalue + 1
于 2016-05-05T11:19:35.037 回答
11

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])
    })
于 2015-12-10T11:57:01.093 回答
5

在 Realm 中,您需要自行管理 auto-inc ID,因此有很多方法可以管理它。下面是其中的一些。

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

每次添加记录时调用此方法。

于 2017-07-26T06:22:37.980 回答
1

我在我的模型中使用了 creationDate,所以我根据这个日期创建了一个Unix 时间戳,并将其用作我的对象的 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
    }
}
于 2016-09-15T08:42:46.527 回答
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)
    }
}
于 2016-12-20T04:42:13.757 回答