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が必要ですか?
そうでない場合は、一意の文字列主キーで十分な場合があります。次に、_[[NSUUID UUID] UUIDString]
_のようなものを使用して、一意の文字列IDを生成できます。これについての良いところは、これらのUUIDが、マルチスレッドのシナリオであっても、一意であることが多少保証されることです。
その場合、最後の数値を常にメモリに保持しておくと、新しいIDを生成するたびにクエリが不要になるため、より効率的です。オブジェクトが複数のスレッドで作成される可能性がある場合は、nextPrimaryKey()
関数をスレッドセーフにするようにしてください。そうしないと、同じ数が2回(またはそれ以上)生成される可能性があります。
Swiftの自動インクリメント主キーにこのコードを使用しています:
var myvalue = realm.objects(ChatData).map{$0.id}.maxElement() ?? 0
myvalue = myvalue + 1
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])
})
Realmでは、自動inc IDを自分で管理する必要があるため、多くの方法で管理できます。以下はその一部です。
func incrementID() -> Int {
let realm = try! Realm()
return (realm.objects(Person.self).max(ofProperty: "id") as Int? ?? 0) + 1
}
レコードを追加するたびにこのメソッドを呼び出します。
これは本質的に、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)
}
}
モデルで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
}
}