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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26252432/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 03:04:29  来源:igfitidea点击:

How do I set a auto increment key in Realm?

iosrealm

提问by drinking

I have a unique msgid for each ChatData object.

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

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

But each time I create a new object I have to query all objects and get the last msgid.

但是每次我创建一个新对象时,我都必须查询所有对象并获取最后一个 msgid。

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

Is there an efficient way to replace this implementation?

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

回答by jpsim

Realm doesn't have auto increment behavior, so you'll need to manage that yourself. A question I'd encourage you to ask yourself about your data:

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

Is it necessary to have sequential, contiguous, integer ID's?

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

If not, then a unique string primary key might be sufficient. Then you can use something like [[NSUUID UUID] UUIDString]to generate unique string ID's. The nice thing about this is that these UUID's are more or less guaranteed to be unique, even in multithreaded scenarios.

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

If so, it might be more efficient to always keep the last number in memory, so that queries aren't required every time a new ID should be generated. If objects might be created in multiple threads, make sure to make your nextPrimaryKey()function thread-safe, otherwise it might generate the same number twice (or more!).

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

回答by Kirit Modi

You are use this Code for Auto Incremental Primary Key in Swift :

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

var myvalue = realm.objects(ChatData).map{
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
    }
}
.id}.maxElement() ?? 0 myvalue = myvalue + 1

回答by Pablo Ruan

Autoincrement id Realm in Swift 2.0: insert code in class realm and object write use

Swift 2.0 中的自动增量 id 领域:在类领域中插入代码和对象写入使用

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

in file write use:

在文件写入中使用:

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

回答by Govaadiyo

In Realm you need to manage auto-inc ID it self so there are many ways to manage it. Below is some of them.

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

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

call this method every time when you adding record.

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

回答by Frédéric Adda

I used a creationDate in my Model, so I created a Unix timeStampbased on this date, and used it as the primaryKey of my object.

我在我的模型中使用了一个 creationDate,所以我根据这个日期创建了一个Unix 时间戳,并将它用作我的对象的主键。

It's 99.99% guaranteed to be unique in my case(because the timestamp is precise to the second), but it may depend on your use case. It's less robust than a UUID, but in many cases it's sufficient.

在我的情况下,它 99.99% 保证是唯一的(因为时间戳精确到秒),但这可能取决于您的用例。它不如 UUID 健壮,但在许多情况下已经足够了。

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

回答by Patrick Goley

This is essentially what is suggested in jpsim's answer, using UUIDto generate unique keys. We query prior to inserting to ensure uniqueness. This will most often only incur one query; in the very rare case of a collision it will continue until it finds a unique id. This solution is a natural extension on the Realmtype and is generic over classes that inherits from Object. The class must implement primaryKeyand return the name of a Stringproperty.

这基本上是 jpsim 的答案中所建议的,UUID用于生成唯一键。我们在插入之前进行查询以确保唯一性。这通常只会产生一个查询;在极少数发生碰撞的情况下,它将继续直到找到唯一的 id。此解决方案是该Realm类型的自然扩展,并且对继承自Object. 该类必须实现primaryKey并返回String属性的名称。

##代码##