Добавление массивов в Realm с помощью swift 3
Я новичок в Realm, и я попытался добавить массив, как я сделал со строками, и я закончил с некоторыми ошибками. Поэтому после небольшого поиска я нашел решение:
class Sensors : Object {
dynamic var name = ""
dynamic var message = ""
var topic: [String] {
get {
return _backingNickNames.map { .stringValue }
}
set {
_backingNickNames.removeAll()
_backingNickNames.append(objectsIn: newValue.map({ RealmString(value: []) }))
}
}
let _backingNickNames = List<RealmString>()
override static func ignoredProperties() -> [String] {
return ["topic"]
}
}
class RealmString: Object {
dynamic var stringValue = ""
}
это работает очень хорошо, теперь я хочу добавить еще один массив внутри класса. Если кто-то знает другие способы добавления массивов с realm, пожалуйста, поделитесь им.
спасибо заранее
3 ответов
как правило, более эффективно использовать отношения "один ко многим", предоставляемые Realm, вместо того, чтобы пытаться эмулировать их с помощью массивов (коллекции Realm ленивы, содержащиеся объекты создаются только при необходимости, в отличие от простых массивов Swift).
в вашем случае, если я правильно понимаю, что вы пытаетесь сделать, вы хотите, чтобы добавить [RealmString]
Swift массивы в _backingNickNames
список.
почему бы не использовать append(objectsIn:)
метод Царство List
класс (см. здесь), как это:
// 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
to topics
и messages
соответственно. Также переименовать RealmString
to Topic
и RealmString1
to Message
.
теперь вы можете легко перебирать, скажем, темы, прикрепленные к датчику, как это:
for topic in sensor1.topics { ... }
или если вы хотите прикрепить сообщение к датчику, вы можете сделать что-то вроде этого (не забудьте правильно добавить вновь созданный объект в БД):
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 { .stringValue }
}
set {
topicV.removeAll()
topicV.append(objectsIn: newValue.map({ RealmString(value: []) }))
}
}
var message: [String] {
get {
return messageV.map { .stringValue1 }
}
set {
messageV.removeAll()
messageV.append(objectsIn: newValue.map({ RealmString1(value: []) }))
}
}
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 может хранить только ссылки на сингулярную область Object
объекты, а также массивы Object
С помощью List
тип. Таким образом, если вы хотите сохранить массив типов, необходимо инкапсулировать любые базовые типы, которые вы хотите сохранить (например,String
здесь) в области удобства Object
.
как сказал богданф, не рекомендуется конвертировать Realm List
S для стандартных массивов Swift и обратно, так как вы теряете преимущества функций ленивой загрузки Realm (которые могут вызвать проблемы с производительностью и памятью), но проблемы с памятью можно по крайней мере смягчить, заключив код, копирующий данные из Realm в @autoreleasepool
блок.
class MyObject: Object {
dynamic var childObject: MyObject?
let objectList = List<MyObject>()
}
Итак, в обзоре, лучше всего работать непосредственно с Realm List
объекты, когда это возможно, и использовать @autoreleasepool
в любое время вы действительно хотите, чтобы цикл через каждый дочерний объект в Сфера. :)