web-dev-qa-db-ja.com

Realmで自動インクリメントキーを設定するにはどうすればよいですか?

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;

この実装を置き換える効率的な方法はありますか?

34
drinking

レルムには自動インクリメント動作がないため、自分で管理する必要があります。データについて自問することをお勧めします。

連続した連続した整数IDが必要ですか?

そうでない場合は、一意の文字列主キーで十分な場合があります。次に、_[[NSUUID UUID] UUIDString]_のようなものを使用して、一意の文字列IDを生成できます。これについての良いところは、これらのUUIDが、マルチスレッドのシナリオであっても、一意であることが多少保証されることです。

その場合、最後の数値を常にメモリに保持しておくと、新しいIDを生成するたびにクエリが不要になるため、より効率的です。オブジェクトが複数のスレッドで作成される可能性がある場合は、nextPrimaryKey()関数をスレッドセーフにするようにしてください。そうしないと、同じ数が2回(またはそれ以上)生成される可能性があります。

51
jpsim

Swiftの自動インクリメント主キーにこのコードを使用しています:

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

Autoincrement id Realm in Swift 2.0:クラスレルムにコードを挿入し、オブジェクトの書き込みを使用

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])
    })
11
Pablo Ruan

Realmでは、自動inc IDを自分で管理する必要があるため、多くの方法で管理できます。以下はその一部です。

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

レコードを追加するたびにこのメソッドを呼び出します。

2
Govaadiyo

これは本質的に、UUIDを使用して一意のキーを生成するjpsimの回答で提案されているものです。挿入前にクエリを実行して、一意性を確保します。ほとんどの場合、1つのクエリのみが発生します。コリジョンの非常にまれなケースでは、一意の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)
    }
}
0
Patrick Goley

モデルでcreationDateを使用したため、この日付に基づいてnix 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
    }
}
0
Frédéric Adda