EditorWindow и SerializedObject.ApplyModifiedProperties(). Как избавиться от ошибки "SerializedObject target has been destroyed"

Имею несколько окошек редактора в которых через диалоги задаю значение свойства. Диалоги большие, с кучей вложенных свойств. В целом работа с окошком выглядит примерно вот так:

using UnityEngine;
using UnityEditor;

public class MyEditorWindow : EditorWindow
{
    [MenuItem("Window/My Editor Window")]
    public static void ShowWindow()
    {
        GetWindow<MyEditorWindow>();
    }

    // список свойств окна к изменению
    public string[] Strings = { "Larry", "Curly", "Moe" };
    // ссылка на сериализованный объект где будут наши свойства окна
    SerializedObject so;

    private void OnEnable()
    {
        //здесь инициируем объект            
        so = new SerializedObject(this);
    }

    void OnGUI()
    {
        so.Update();
        //дальше выводим нужный интерфейс через EditorGUILayout, а ля
        SerializedProperty stringsProperty = so.FindProperty("Strings");    
        EditorGUILayout.PropertyField(stringsProperty, true); 

        so.ApplyModifiedProperties(); // Вот здесь периодически и падает ошибка
    }
}

Через поиск встречал, что существует проблема с тем, что при потере фокуса объекта в сцене, а также перехода между диалоговыми окнами в точке где идет обновление свойств объекта so.ApplyModifiedProperties(); частенько редактор генерирует ошибку

SerializedObject target has been destroyed

пробовал заключать отрисовку в BeginChange и EndChange, но это не спасает. На целостность данных в диалогах вроде это не влияет, но раздражает.

Кто-то знает как с этим бороться?


Ответы (2 шт):

Автор решения: Yaroslav

Вообще разработчики не хотят что-бы кто-то сам создавал SerializedObject и в документации даже нет описания его свойств, кто такие inspectorMode или inspectorDataMode, которые указываются в Editor.cs... ну хер его знает. Уж тем более писал такую порнуху как new SerializedObject(this) точно никто не предусматривал и бороться тут не с чем.

SerializedObject стримит данные и является IDisposable и за его жизненным циклом нужно следить. Это прописано в классе Editor, у которого есть target для которого создаётся и уничтожается SerializedObject. При использовании в инспекторе, target присваивается автоматически в контексте выбранного объекта, но можно легко делать это и в ручную, если речь не о инспекторе.

По идее и вообще по принципам программирования, модели данных должны быть отделены от визуализации. То есть массив не должен быть среди полей EditorWindow, потому что окно выступает в роли view. В EditorWindow нужно выстраивать композицию из набора Editor просто вызывая их OnGUI и используя EditorGUI по мелочи.

→ Ссылка
Автор решения: KingPeas

Нашел причину, из-за чего появлялась ошибка. Внутри OnGUI выводился интерфейс и была кнопочка по которой обновлялось свойство в родительском окне и собственно само диалоговое окно закрывалось. Получалось что окно закрыто, но OnGUI еще дорисовывает интерфейс диалога которого нет.

Так что все, что требовалось - это вызывать процедуру закрытия окна после того как интерфейс будет отрисован и отработает so.ApplyModifiedProperties();

→ Ссылка