Подтвердить что ты не робот

Как установить ключ автоматического увеличения в Realm?

У меня есть уникальный ресурс для каждого объекта ChatData.

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

Но каждый раз, когда я создаю новый объект, я должен запросить все объекты и получить последнее сообщение.

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

Есть ли эффективный способ заменить эту реализацию?

4b9b3361

Ответ 1

Царство не имеет автоматического прироста поведения, поэтому вам нужно будет управлять этим самостоятельно. Вопрос, который я хотел бы предложить вам узнать о ваших данных:

Нужно ли иметь последовательные, смежные, целочисленные идентификаторы?

Если нет, то может быть достаточно первичного ключа с уникальной строкой. Затем вы можете использовать что-то вроде [[NSUUID UUID] UUIDString] для генерации уникальных идентификаторов строк. Самое приятное в этом состоит в том, что эти UUID более или менее гарантированно уникальны даже в многопоточных сценариях.

Если это так, может быть более эффективным всегда сохранять последний номер в памяти, чтобы запросы не требовались каждый раз, когда должен был быть создан новый идентификатор. Если объекты могут быть созданы в нескольких потоках, убедитесь, что ваша функция nextPrimaryKey() потокобезопасна, иначе она может генерировать один и тот же номер дважды (или больше!).

Ответ 2

Автоинкремент id Realm в 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])
    })

Ответ 3

Вы используете этот код для автоматического инкрементного первичного ключа в Swift:

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

Ответ 4

Я использовал createDate в моей модели, поэтому я создал Unix 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
    }
}

Ответ 5

Это, по сути, то, что предлагается в jpsim-ответе, используя UUID для создания уникальных ключей. Мы запрашиваем перед вставкой, чтобы обеспечить уникальность. Это чаще всего будет выполнять только один запрос; в очень редком случае столкновения он будет продолжаться до тех пор, пока не найдет уникальный идентификатор. Это решение является естественным расширением типа 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)
    }
}

Ответ 6

В Realm вам нужно управлять идентификатором auto-inc ID, поэтому есть много способов управлять им. Ниже приведены некоторые из них.

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

вызывать этот метод каждый раз при добавлении записи.