【问题标题】:How can I generate ids for objects in RealmSwift?如何在 RealmSwift 中为对象生成 id?
【发布时间】:2016-05-14 14:54:55
【问题描述】:

我正在使用 RealmSwift。为对象生成 id 的最佳/规范方法是什么?

这是我想出的:

class MyObject: Object {
    dynamic var id = ""
    dynamic var createdAt = NSDate()

    override class func primaryKey() -> String {
        return "id"
    }

    func save() {
        let realm = try! Realm()

        if(self.id == "") {
            while(true) {
                let newId = NSUUID().UUIDString
                let saying = realm.objectForPrimaryKey(MyObject.self, key: newId)
                if(saying == nil) {
                    self.id = newId
                    break
                }
            }
        }

        try! realm.write {
            realm.add(self)
        }
    }
}

我想要一个将对象持久保存到 Realm 并根据 id 覆盖或创建新对象的函数。这似乎工作正常,但我不确定领域中是否有内置的东西可以做到这一点。还是有更好的办法?

谢谢。

【问题讨论】:

    标签: swift realm


    【解决方案1】:

    我知道这已经几个月了,但这就是我实现自动递增主键的方式。

    此代码未经测试,但您会大致了解

    class MyObject: Object {
        /**
        Primary Key
    
        Since you can't change the primary key after the object is saved,
        we'll use 0 to signify an unsaved object. When we set the primary key,
        we'll never use 0.
        */
        dynamic var id: Int = 0
    
        /**
        Some persisted value
        */
        dynamic var someString: String?
    
        var nextID: Int {
            do {
                let realm = try Realm()
    
                /// I would use .max() but Realm only supports String and signed Int for primary keys
                /// so using overflow protection, the `next` primary key would be Int.min if the
                /// current value is Int.max
                var id = realm.objects(MyObject.self).sorted("id", ascending: true).last?.id ?? 0
    
                /// add 1 to id until we find one that's not in use... skip 0
                repeat {
                    id = Int.addWithOverflow(id, 1).0 /// Add with overflow in case we hit Int.max
                } while id == 0 || realm.objectForPrimaryKey(MyObject.self, key: id) != nil
    
                return id
            } catch let error as NSError {
                /// Oops
                fatal(error: error.localizedDescription)
            }
        }
    
        convenience init(someString: String?) {
            self.init()
    
            id = nextID
            self.someString = someString
            save()
        }
    
        override class func primaryKey() -> String? {
            return "id"
        }
    
        func save() {
            /// Gotta check this in case the object was created without using the convenience init
            if id == 0 { id = nextID }
    
            do {
                let realm = try Realm()
                try realm.write {
                    /// Add... or update if already exists
                    realm.add(self, update: true)
                }
            } catch let error as NSError {
                fatalError(error.localizedDescription)
            }
        }
    }
    

    创建唯一字符串ID(即:一个UUID)的过程非常相似:

    class MyObject: Object {
        /**
        Primary Key
        */
        dynamic var id: String = ""
    
        /**
        Some persisted value
        */
        dynamic var someString: String?
    
        var nextID: String {
            do {
                let realm = try Realm()
    
                var id: String = NSUUID().UUIDString
    
                /// NSUUID().UUIDString almost always makes a unique ID on the first try
                /// but we'll check after we generate the first one just to be sure
                while realm.objectForPrimaryKey(MyObject.self, key: id) != nil {
                    id = NSUUID().UUIDString
                }
    
                return id
            } catch let error as NSError {
                /// Oops
                fatal(error: error.localizedDescription)
            }
        }
    
        convenience init(someString: String?) {
            self.init()
    
            id = nextID
            self.someString = someString
            save()
        }
    
        override class func primaryKey() -> String? {
            return "id"
        }
    
        func save() {
            /// Gotta check this in case the object was created without using the convenience init
            if id == "" { id = nextID }
    
            do {
                let realm = try Realm()
                try realm.write {
                    /// Add... or update if already exists
                    realm.add(self, update: true)
                }
            } catch let error as NSError {
                fatalError(error.localizedDescription)
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      Realm(Swift) 目前不支持自增主键。您可以像上面一样设置主键,但对于自动递增和唯一键,您可以使用以下几种方法:

      1. UUID(就像你上面所说的)
      2. 查询对象的最大“id”(主键)并将要插入的对象设置为 id + 1。类似...

        let id = realm.objects(MyObject).max("id") + 1

      3. 创建您自己的哈希签名(一个可能的示例:SHA256(epoch timestamp + SHA256(object.values))

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多