Добавление массивов в 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 ListS для стандартных массивов Swift и обратно, так как вы теряете преимущества функций ленивой загрузки Realm (которые могут вызвать проблемы с производительностью и памятью), но проблемы с памятью можно по крайней мере смягчить, заключив код, копирующий данные из Realm в @autoreleasepool блок.

class MyObject: Object {
    dynamic var childObject: MyObject?
    let objectList = List<MyObject>()
}

Итак, в обзоре, лучше всего работать непосредственно с Realm List объекты, когда это возможно, и использовать @autoreleasepool в любое время вы действительно хотите, чтобы цикл через каждый дочерний объект в Сфера. :)