我目前正在使用Realm在swift中实现我的第一个应用程序。我很喜欢!但是,我试图让我的模特"好"但我真的觉得我让它们变得更糟。这是一个示例模型:
import RealmSwift
class Location : Object {
dynamic var ident = ""
dynamic var package = ""
dynamic var title = ""
dynamic var is_selected = false
let contentSets = List<ContentSet>()
convenience init(ident : String, package: String, title : String, is_selected : Bool) {
self.init()
self.ident = ident
self.package = package
self.title = title
self.is_selected = is_selected
}
override static func primaryKey() -> String? {
return "ident"
}
func save() {
let realm = try! Realm()
try! realm.write {
realm.add(self)
}
}
static func findAll() -> Results<Location> {
return try! Realm().objects(Location)
}
static func findByIdent(ident : String) -> Location?{
return try! Realm().objects(Location).filter("ident == %@", ident).first as Location?
}
static func getSelected() -> Location? {
return try! Realm().objects(Location).filter("is_selected == true").first as Location?
}
func hasContentSetByObject(contentSet : ContentSet) -> Bool {
return self.hasContentSetByString(contentSet.ident)
}
func addContentSet(contentSet: ContentSet) {
let realm = try! Realm()
try! realm.write {
self.contentSets.append(contentSet)
}
}
func isSelected(value: Bool) {
let realm = try! Realm()
let selectedLocation = Location.getSelected()
selectedLocation?.isSelected(false)
try! realm.write {
self.is_selected = value
try! realm.commitWrite()
}
}
func hasContentSetByString(ident : String) -> Bool {
let result = self.contentSets.filter{$0.ident == ident}.count > 0 ? true : false
return result
}
}
我的想法是,保持与我的控制器相关的所有内容。但是,关于模型的更新数据,我认为这种方法很糟糕,因为它消除了Realm的很多灵活性。
你们是怎么做那种东西的?期待您的投入。
此致 SantoDE
答案 0 :(得分:1)
您可以保留&#34;关注点分离&#34;而不必牺牲Realm的事务性变异模型或其查询语法的内部结构的整个基本原理。
以下是一些提示:
从您的小样本中,有10个可用的调用(try!
),没有错误处理。这是一种代码味道。如同,不一定是错误的,但应该让你仔细看看并重新考虑模式。
即使你在每种情况下都处理错误,这也会很乏味且容易出错。
相反,为什么不尽可能地将错误处理保持为本地化,从而产生更简单的代码,更少的重复和更少的未处理错误机会?
您可以通过使用依赖项注入,将Realm
实例从模型方法中提取出来,并将Realm实例传递给需要它的代码部分来实现此目的。
Realm Swift大量使用Swift的泛型系统,产生像这样冗余的动态转换:
try! Realm().objects(Location).filter("ident == %@", ident).first as Location?
因为以下内容更安全,因为没有机会使用错误类型:
try! Realm().objects(Location).filter("ident == %@", ident).first
此代码:
try! realm.write {
self.is_selected = value
try! realm.commitWrite()
}
不正确,因为Realm.write(_:)
调用在调用传入闭包后会自动调用Realm.commitWrite()
。所以只需替换为:
try! realm.write {
self.is_selected = value
}
这样的代码强制Realm将其所有对象实现为Swift对象,这些对象的执行效果非常差:
let result = self.contentSets.filter{$0.ident == ident}.count > 0 ? true : false
return result
相反,您应该更喜欢Realm的本机查询系统,该系统针对Realm数据进行了优化:
return !contentSets.filter("ident == %@", ident).isEmpty
总的来说,我还说如果你发现自己以关注点分离的名义编写许多代码,那么你真正获得了什么?