我知道关于这个主题有很多线索,但是我觉得我有点不同,因为我没有保存或从DB中获取对象,而且它们一直在主线程上 .
我的问题非常糟糕,我可以在同一个类中修改realm对象但是当我将它作为参数传递给另一个时,那么就会发生类似的事情 . 我想知道为什么会这样?它不应该发生 .
'RLMException', reason: 'Attempting to modify object outside of a write transaction - call beginWriteTransaction on an RLMRealm instance first.'
这是我的数据库结构:
- Persistable 是数据库中每个对象共享的协议 .
public protocol Persistable {
associatedtype PropertyValue: PropertyValueType
associatedtype ManagedObject: RealmSwift.Object
associatedtype Query: QueryType
init(managedObject: ManagedObject)
func getManagedObject() -> ManagedObject
}
public typealias PropertyValuePair = (name: String, value: Any)
public protocol PropertyValueType {
var propertyValuePair: PropertyValuePair { get }
}
public protocol QueryType {
var predicate: NSPredicate? { get }
var sortDescriptors: [SortDescriptor] { get }
}
- Container 上课:
public final class Container {
let realm: Realm
public convenience init() throws {
try self.init(realm: Realm())
}
internal init(realm: Realm) {
self.realm = realm
}
public func objects<T: Persistable>(_ type: T.Type) throws -> Results<T.ManagedObject> {
return realm.objects(type.ManagedObject.self)
}
public func write(_ block: (WriteTransaction) throws -> Void) throws {
let transaction = WriteTransaction(realm: realm)
try realm.write {
try block(transaction)
}
}
public func values<T> (_type: T.Type, maching query: T.Query) -> FetchResults<T> {
var results = realm.objects(T.ManagedObject.self)
if let predicate = query.predicate {
results = results.filter(predicate)
}
if !results.isEmpty {
results = results.sorted(by: query.sortDescriptors)
}
return FetchResults(results: results)
}
}
- WriteTransaction 类处理所有添加,更新,删除的事件(尚未实现)
public final class WriteTransaction {let realm:Realm
internal init(realm: Realm) {
self.realm = realm
}
public func add<T: Persistable>(_ value: T, update: Bool) {
realm.add(value.getManagedObject(), update: update)
}
public func update<T: Persistable>(_ type: T.Type, values:[T.PropertyValue]) {
var dictionary: [String: Any] = [:]
values.forEach {
let pair = $0.propertyValuePair
dictionary[pair.name] = pair.value
}
realm.create(T.ManagedObject.self, value: dictionary, update: true)
}
public func delete<T: Persistable>(_ value: T) {
// TODO: Make it better.
// guard let objc = realm.object(ofType:T.self,forPrimaryKey:value.getId())else // realm.delete(objc)}}
- 并且对于提取对象 FetchResults :
公共最终类FetchResults {
internal let results: Results<T.ManagedObject>
public var count: Int {
return results.count
}
internal init(results: Results<T.ManagedObject>) {
self.results = results
}
public func value(at index: Int) -> T {
return T(managedObject: results[index])
}
}
示例代码为:
我获取对象的第一类:
FirstClass
这是一个全球宣言:
... Event: Object
var events: [Event]!
在其中一个方法中,同一个类 - >作为一个魅力:
让我们通过这个方法获取一些对象:( DataBaseManager是一个单例)
events = DataBaseManager.Instance.getObjects(Event.self, try! Container(), matching: .eventsFromPastDaysForOwner(username, Int(Date().timeIntervalSince1970) - 691200))
getObjects(...)
的实施:
func getObjects<T, C>(_ type: T.Type, _ container: C, matching: T.Query) -> [T] where T : Persistable, C : Container {
var objects = [T]()
let fetchedObjects = container.values(_type: type, maching: matching)
for i in 0..<fetchedObjects.count {
objects.append(fetchedObjects.value(at: i))
}
return objects
}
如果没有对象,我们创建它们:
if events.isEmpty {
events.append(Event(something: Something, something2: Something2))
}
我们可以轻松修改它们:
events[0].something = Something3
对于这个例子,我们坚持使用空列表 . 向前迈进 .
- 传递创建的事件(列表中只有一个元素/它无关紧要):
func getEventsDurations(_ events:[Event]) - > [Event]
对事件有一些计算,但崩溃的线是:
events.first?.something = 0
我们用新值修改对象的行 .
为什么会这样?当我修改类中的领域对象时,我确实获取它没关系,但在其他类中得到了这个崩溃?
我很抱歉有很多代码,但是如果有人想看一下数据库结构的话 .
顺便说一句 . 我可以解决并在写入事务中放置每个修改:
try! container.write({ transaction in
// Doing nothing, just modifying objects.
})
来吧,这太丑了 .
提前致谢!
1 回答
您可以在保存之前在任何位置修改新创建的对象 . 但是如果它是从域中获取/保存到域中的对象,那么您使用域事务处理 must .