このトピックに関するスレッドがたくさんあることは知っていますが、DBからオブジェクトを保存またはフェッチしていないため、メインスレッド上に常にあるので、 。書き込みトランザクション外のオブジェクトを変更する
私の問題はかなり厄介です。私は同じクラスのrealmオブジェクトを変更できますが、別のインスタンスに引数として渡すとそのようなものが発生します。私はなぜそれが起こっているのか理解しようとしていますか?それは起こるべきではありません。ここ
'RLMException', reason: 'Attempting to modify object outside of a write transaction - call beginWriteTransaction on an RLMRealm instance first.'
は私のデータベース構造である:
永続データベース内の各オブジェクトによって共有されるプロトコルです。
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 } }
コンテナクラス:追加、更新、削除するためのイベントの全てを処理
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クラス(未実装)
公衆finalクラスWriteTransaction { LETレルム:レルム
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.
//ガードせにObjC = realm.object(ofType:T.self、forPrimaryKey:value.getId())他{リターン} // realm.delete(にObjC) }}
そしてフェッチがFetchResultsオブジェクトの場合:
パブリック最終クラスFetchResults {
を
例のコードは次のようになります。私は、オブジェクトをフェッチ
ファーストクラス:
FirstClassの
ここでグローバル宣言です:
...イベント:オブジェクト{...}方法の一つで
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
}
オブジェクトがない場合l ETSはそれらを作成します。
if events.isEmpty {
events.append(Event(something: Something, something2: Something2))
}
我々はイースリー、それらを変更することができます。
events[0].something = Something3
この例では、我々は空のリストに固執します。ポイントに進む。
パッシングがイベントを作成し(リスト内の唯一の要素を/それがどんなに多くのdoesntの):
FUNCのgetEventsDurations(_イベント:[イベント]) - > [イベント]
events.first?.something = 0
:イベントのいくつかの計算を持っているが、そこでクラッシュライン
彼は新しい価値を持っています。
どうしてですか?フェイルしたときにクラスの領域オブジェクトを変更すると、それは大丈夫でしたが、他のクラスではこのクラッシュがありましたか?
大変申し訳ありませんが、誰かがデータベースの構造を見たいと思っている場合に備えてです。
Btw。私は仕事をして、すべての変更を書き込みトランザクションの中に置くことができました:
try! container.write({ transaction in
// Doing nothing, just modifying objects.
})
私はそれが醜いです。
ありがとうございます!
フェッチされたオブジェクトに対してレルムトランザクションを使用する必要があります。フェッチされた領域オブジェクトとデータベース内のオンの間には参照があるようです。それは効率的ですか? – yerpy
効率的です。なぜデータベースが動作するのかを知りたいのであれば、私たちのウェブサイトにはたくさんのドキュメントがあります(この記事をチェックしてください:https://academy.realm.io/posts/jp-simard-realm-core-データベースエンジン/)。 – AustinZ