Не удается найти ошибку класса символов в kotlin Привязка данных с помощью KOIN + Room в Android Studio 3.2.1 9 октября, сборка 2018 г.

Предполагаю, что вы используете BinaryFormatter .

BinaryFormatter - сериализатор графа. Вместо того, чтобы объекты хранятся в чистом дереве, им присваиваются временные идентификаторы объектов и хранятся в том виде, в котором они встречаются. Таким образом, когда объект десериализуется, не гарантируется, что все ссылочные объекты были ранее десериализованы. Таким образом, записи в вашем forwardMap еще не заполнены.

Обычным обходным путем является добавление логики IDeserializationCallback в ваш класс и создание ваших inverseMap и inverseInstance после того, как все было десериализовано в OnDeserialization . Но Dictionary также реализует IDeserializationCallback , что вводит дополнительную проблему секвенсирования: она не гарантируется, что она была вызвана до вашего. В этой теме Microsoft пишет :

Объекты реконструируются изнутри, а вызывающие методы во время десериализации могут иметь нежелательные побочные эффекты, поскольку вызванные методы могут ссылаться на ссылки на объекты, которые не были десериализованы к моменту вызова. Если десериализованный класс реализует IDeserializationCallback, метод OnSerialization будет автоматически вызываться, когда весь объектный граф будет десериализован. На этом этапе все дочерние объекты, на которые делается ссылка, были полностью восстановлены. Хэш-таблица является типичным примером класса, который трудно десериализовать без использования прослушивателя событий, описанного выше. Легко получить пары ключ / значение во время десериализации, но добавление этих объектов обратно в хеш-таблицу может вызвать проблемы, поскольку нет гарантии, что классы, полученные из хеш-таблицы, были десериализованы. Поэтому методы вызова в хеш-таблице на этом этапе нецелесообразны.

blockquote>

Таким образом, есть несколько вещей, которые вы могли бы сделать:

  1. Вместо того, чтобы хранить Dictionary, сохраните массив из KeyValuePair. Это имеет преимущество, заключающееся в том, что ваши двоичные данные проще, но вам требуется выделить массив в вашем GetObjectData() методе.
  2. Или следовать рекомендациям в справочном источнике словаря :
    // It might be necessary to call OnDeserialization from a container if the container object also implements
    // OnDeserialization. However, remoting will call OnDeserialization again.
    // We can return immediately if this function is called twice. 
    // Note we set remove the serialization info from the table at the end of this method.
    
    Т.е. в своем обратном вызове вызовите метод OnDeserialization вашего вложенного словаря перед его использованием:
    public partial class BidirectionalDictionary : IDeserializationCallback
    {
        public void OnDeserialization(object sender)
        {
            this.forwardMap.OnDeserialization(sender);
            foreach (KeyValuePair entry in forwardMap)
            {
                this.inverseMap.Add(entry.Value, entry.Key);
            }
            // inverseInstance will no longer be able to be read-only sicne it is being allocated in a post-deserialization callback.
            this.inverseInstance = new BidirectionalDictionary(this);
        }
    
    (вместо этого вы можете сделать это в методе [OnDeserialied] .)

Кстати, это сообщение в блоге утверждает, что безопасно вызывать метод OnDeserialization для HashTable из конструктора десериализации содержащего класс , а не позже OnDeserialization, чтобы вы могли попробовать.

0
задан Sandip Savaliya 30 December 2018 в 14:33
поделиться