首页 文章

修改写入事务之外的对象

提问于
浏览
0

我知道关于这个主题有很多线索,但是我觉得我有点不同,因为我没有保存或从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 回答

  • 3

    您可以在保存之前在任何位置修改新创建的对象 . 但是如果它是从域中获取/保存到域中的对象,那么您使用域事务处理 must .

相关问题