私はRealmの初心者で、文字列で行ったように配列を追加しようとすると、いくつかのエラーが発生しました。だから少し検索した後、私は解決策を見つけました:
class Sensors : Object {
dynamic var name = ""
dynamic var message = ""
var topic: [String] {
get {
return _backingNickNames.map { $0.stringValue }
}
set {
_backingNickNames.removeAll()
_backingNickNames.append(objectsIn: newValue.map({ RealmString(value: [$0]) }))
}
}
let _backingNickNames = List<RealmString>()
override static func ignoredProperties() -> [String] {
return ["topic"]
}
}
class RealmString: Object {
dynamic var stringValue = ""
}
これは非常にうまく機能しているので、このクラス内に別の配列を追加したいと思います。レルムで配列を追加する他の方法を誰かが知っている場合は、それを共有してください。
前もって感謝します
一般的な規則として、配列を使用してそれらをエミュレートしようとする代わりに、Realmによって提供される1対多の関係を使用する方が効率的です(Realmのコレクションは遅延であり、含まれるオブジェクトは、プレーンSwift配列)。
あなたの場合、あなたが何をしようとしているのかを私が正しく理解しているなら、_[RealmString]
_リストに__backingNickNames
_ Swift配列を追加する必要があります。
次のように、レルムのList
クラスのappend(objectsIn:)
メソッドを使用しないでください( here を参照)。
_// Dog model
class Dog: Object {
dynamic var name = ""
dynamic var owner: Person?
}
// Person model
class Person: Object {
dynamic var name = ""
dynamic var birthdate = NSDate(timeIntervalSince1970: 1)
let dogs = List<Dog>()
}
let jim = Person()
let dog1 = Dog()
let dog2 = Dog()
// here is where the magic happens
jim.dogs.append(objectsIn: [dog1, dog2])
_
反対のことをしたい場合(リストから配列に変換)は次のようにします:
_let dogsArray = Array(jim.dogs)
_
••••••••
独自の投稿されたソリューション に戻ると、これに対応するためにモデルを簡単にリファクタリングできます。各Sensor
オブジェクトには、いくつかのTopic
およびいくつかのMessage
オブジェクトをアタッチできます。
message
とtopic
の計算済みプロパティを破棄し、topicV
とmessageV
の名前をそれぞれtopics
とmessages
に変更します。また、RealmString
をTopic
に、_RealmString1
_をMessage
に名前変更します。
これで、たとえば次のようなセンサーに接続されたトピックを簡単に反復できます。
_for topic in sensor1.topics { ... }
_
または、センサーにメッセージを添付する場合は、次のようなことを実行できます(最初にDBに新しく作成したオブジェクトを 適切に追加 することを忘れないでください)。
_let message1 = Message()
message1.stringValue = "Some text"
sensor2.messages.append(message1)
_
したがって、中間のSwift配列を使用する必要はありません。
テストした後、そのような別の配列を追加することができました。
class Sensors : Object {
dynamic var type = ""
dynamic var name = ""
dynamic var badge = 0
var topic: [String] {
get {
return topicV.map { $0.stringValue }
}
set {
topicV.removeAll()
topicV.append(objectsIn: newValue.map({ RealmString(value: [$0]) }))
}
}
var message: [String] {
get {
return messageV.map { $0.stringValue1 }
}
set {
messageV.removeAll()
messageV.append(objectsIn: newValue.map({ RealmString1(value: [$0]) }))
}
}
let topicV = List<RealmString>()
let messageV = List<RealmString1>()
override static func ignoredProperties() -> [String] {
return ["topic", "message"]
}
}
class RealmString: Object {
dynamic var stringValue = ""
}
class RealmString1: Object {
dynamic var stringValue1 = ""
}
Bogdanfの発言と、それを実装した方法はどちらも正しいです。
基本的な値タイプは別として、Realmは、単一のRealm Object
オブジェクトへの参照と、Object
タイプを使用するList
sの配列のみを格納できます。そのため、型の配列を保存する場合は、保存する基本的な型(ここではString
など)を便利なレルムObject
にカプセル化する必要があります。
Bogdanfが言ったように、Realmの遅延読み込み機能(両方のパフォーマンスを引き起こす可能性がある)の利点を失うので、Realm List
sを標準のSwift配列に変換して再度戻すことはお勧めしません。およびメモリの問題)が、レルムからデータをコピーするコードを@autoreleasepool
ブロックで囲むことにより、メモリの問題を少なくとも軽減できます。
class MyObject: Object {
dynamic var childObject: MyObject?
let objectList = List<MyObject>()
}
したがって、レビューでは、可能な限りRealm List
オブジェクトを直接操作し、Realm内のすべての子オブジェクトを実際にループしたい場合はいつでも@autoreleasepool
を使用することをお勧めします。 :)