我爱领域,我爱邦德。两者都使应用程序的创建成为joy。所以我想知道连接王国和邦德的最好方法是什么?
在领域中,我们可以存储基本类型,如Int、String,但在邦德中,我们使用Dynamic和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
}
}但是它确实缺乏简洁和优雅,并且产生了大量的锅炉代码。有办法做得更好吗?
发布于 2015-03-21 14:58:27
我已经想了三天了,想出了一个几乎完美的解决方案,它不使用任何样板代码。首先,我为领域模型的包装器创建了一个超类:
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() }
}这两个类实际上都是链接Realm和Bond所需要的:创建新的TodoModel实际上将向领域添加新的RealmTodoModel,使用TodoModel的title和date所做的所有更改都将自动保存到相应的Realm模型中!
编辑
我添加了一些功能,并将其作为一个框架发布在GitHub上。这是链接。
发布于 2015-03-20 23:47:46
如果使用缺省属性值,则可能会简化所使用的模式:
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的->>运算符返回左值,则可以删除另外两行代码,这样就可以执行self.title = Dynamic<String>(title) ->> titleBond了。
但最终,在Swift对KVO或类似的观察机制提供母语支持之前,您将不得不编写一些样板。
https://stackoverflow.com/questions/29155556
复制相似问题