【问题标题】:What is the best way to connect Realm and SwiftBond连接 Realm 和 SwiftBond 的最佳方式是什么
【发布时间】:2015-05-23 05:09:03
【问题描述】:

我喜欢Realm,我也喜欢Bond。它们都使应用程序创建成为一种乐趣。所以我想知道连接 Realm 和 Bond 的最佳方式是什么?
在 Realm 中,我们可以存储基本类型,例如 IntString,例如但在 Bond 中,我们与 Dynamics 和 Bonds 合作。我发现连接 Realm 和 Bond 的唯一方法如下:

class TestObject: RLMObject {

   dynamic var rlmTitle: String = ""
   dynamic var rlmSubtitle: String = ""

   var title: Dynamic<String>
   var subtitle: Dynamic<String>

   private let titleBond: Bond<String>!
   private let subtitleBond: Bond<String>!

   init(title: String, subtitle: String) {
      self.title = Dynamic<String>(title)
      self.subtitle = Dynamic<String>(subtitle)

      super.init()

      self.titleBond = Bond<String>() { [unowned self] title in self.rlmTitle = title }
      self.subtitleBond = Bond<String>() { [unowned self] subtitle in self.rlmSubtitle = subtitle }

      self.title ->> titleBond
      self.subtitle ->> subtitleBond
   }
}

但它确实缺乏简洁和优雅,并且产生了大量的锅炉代码。有没有办法更好地做到这一点?

【问题讨论】:

  • 关于这个问题的任何更新?现在有官方方法可以实现吗?

标签: ios swift architecture realm swiftbond


【解决方案1】:

如果您使用过,您可能会在一定程度上简化您正在使用的模式 默认属性值:

  class TestObject: RLMObject {

     dynamic var rlmTitle = ""
     dynamic var rlmSubtitle = ""

     var title: Dynamic<String>
     var subtitle: Dynamic<String>

     private let titleBond = Bond<String>() { [unowned self] title in self.rlmTitle = title }
     private let subtitleBond = Bond<String>() { [unowned self] subtitle in self.rlmSubtitle = subtitle }

     init(title: String, subtitle: String) {
        self.title = Dynamic<String>(title)
        self.subtitle = Dynamic<String>(subtitle)
        self.title ->> titleBond
        self.subtitle ->> subtitleBond

        super.init()
     }
  }

如果 Bond 的 -&gt;&gt; 运算符返回了 左值所以你可以做self.title = Dynamic&lt;String&gt;(title) -&gt;&gt; titleBond

但最终,在 Swift 为 KVO 或等效的观察机制提供本地语言支持之前,您将不得不编写一些样板文件。

【讨论】:

  • 感谢您的回答!实际上我找到了更好的方法来做到这一点,请看我的回答。如果非常欢迎改进它
【解决方案2】:

我已经考虑了三天,并提出了几乎完美的解决方案,它不使用任何样板代码。首先,我为领域模型的包装器创建了一个超类:

class BondRealmBaseClass {

   private var realmModel: RLMObject!
   private let realm = RLMRealm.defaultRealm()
   private var bonds = NSMutableArray()

   init(){
      realmModel = createRealmModel()
      realm.beginWriteTransaction()
      realm.addObject(realmModel)
      realm.commitWriteTransaction()
      createBonds()
   }

   init(realmModel: RLMObject){
      self.realmModel = realmModel
      createBonds()
   }

   func createBondFrom<T>(from: Dynamic<T>, toModelKeyPath keyPath: String){
      from.value = realmModel.valueForKeyPath(keyPath) as T
      let bond = Bond<T>() { [unowned self] value in
         self.realm.beginWriteTransaction()
         self.realmModel.setValue(value as NSObject, forKey: keyPath)
         self.realm.commitWriteTransaction()
      }
      from ->| bond
      bonds.addObject(bond)
   }

   //MARK: - Should be overriden by super classes
   func createBonds(){ fatalError("should be implemented in supreclass") }
   func createRealmModel() -> RLMObject{ fatalError("should be implemented in supreclass") }
}

之后我为每个领域模型创建了两个类,第一个是实际的领域模型,它存储所有属性:

class RealmTodoModel: RLMObject { 
   dynamic var title = ""
   dynamic var date = NSDate()
}

第二个是领域模型的包装器:

class TodoModel : BondRealmBaseClass{
   let title = Dynamic("")
   let date = Dynamic(NSDate())

   override func createBonds(){
      createBondFrom(title, toModelKeyPath: "title")
      createBondFrom(date, toModelKeyPath: "date")
   }

   override func createRealmModel() -> RLMObject { return RealmTodoModel() }
}

这两个类实际上是链接RealmBond所需要的:创建新的TodoModel实际上将添加到Realm新的RealmTodoModel以及使用TodoModeltitle所做的所有更改和date 会自动保存到对应的Realm 模型中!

编辑

我添加了一些功能并将其作为框架发布在 GitHub 上。这是link

【讨论】:

  • 链接似乎不再有效。你的框架有什么更新吗?
【解决方案3】:

Realm 支持 KVO 和 Bond 4,您可以扩展 Realm 对象以提供 Observable 变体。它有一些样板,但它很干净,没有黑客攻击。

class Dog: Object {
  dynamic var name = ""
  dynamic var birthdate = NSDate(timeIntervalSince1970: 1)
}

extension Dog {

  class ObservableDog {
    let name: Observable<String>
    let birthdate: Observable<NSDate>

    init(dog: Dog) {
      name = Observable(object: dog, keyPath: "name")
      birthdate = Observable(object: dog, keyPath: "birthdate")
    }
  }

  func observableVariant() -> Dog.ObservableDog {
    return ObservableDog(dog: self)
  }
}

比你能做到的:

let myDog = Dog().observableVariant()

myDog.name.observe { newName in
  print(newName)
}

myDog.name.bindTo(nameLabel.bnd_text)

realm.write {
  myDog.name.value = "Jim"
}

【讨论】:

  • 在 Dog 上有 var List&lt;Food&gt; = List() 时是否有类似的可能?即,观察此列表的变化。
猜你喜欢
  • 1970-01-01
  • 2010-09-10
  • 2017-07-31
  • 2014-03-19
  • 1970-01-01
  • 2017-04-22
  • 2021-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多