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

Ios 如何在域中设置自动递增键?,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

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

是否有一种有效的方法来替换此实现?

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

是否需要有连续的整数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}