Почему реквизиты формы остаются доступны после ее закрытия в 1С?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При разработке пользовательских интерфейсов в 1С разработчики часто сталкиваются с ситуацией, когда после открытия и последующего закрытия подчиненной или произвольной формы из кода формы-родителя удается беспрепятственно прочитать значения ее реквизитов. На первый взгляд это может показаться странным: почему после закрытия окна данные не уничтожаются?

Проанализируем ситуацию на примере следующего участка кода:


ФормаСерии = ПолучитьФорму("ФормаСерии");
ФормаСерии.ВладелецФормы = ЭтаФорма;
ФормаСерии.ОткрытьМодально();

// После закрытия окна ФормаСерии считываем реквизит:
ЗначениеСрока = ФормаСерии.СрокГодности;

Выясним причину такого поведения платформы 1С и разберем, как правильно работать с данными подчиненных форм.

Жизненный цикл объекта формы в оперативной памяти

Главный нюанс заключается в разделении графического отображения формы (окна пользовательского интерфейса) и программного объекта формы в оперативной памяти компьютера.

Рассмотрим подробнее, что происходит при вызове методов работы с формой:

  1. При вызове функции ПолучитьФорму() платформа создает в памяти экземпляр объекта формы и возвращает ссылку на него в переменную (в нашем примере — ФормаСерии).
  2. Метод ОткрытьМодально() или Открыть() отвечает исключительно за визуальное отображение созданной формы на экране и запуск пользовательского взаимодействия.
  3. Когда пользователь нажимает кнопку закрытия или в коде срабатывает вызов Закрыть(), платформа убирает графическое окно с экрана и вызывает событие ПриЗакрытии.

Однако сам программный объект формы не уничтожается мгновенно. Ссылка на объект формы продолжает храниться в локальной переменной ФормаСерии. Пока эта ссылка находится в области видимости выполняемой процедуры, реквизиты формы остаются полностью доступными для чтения и изменения из кода родительской формы.

Опасность утечек памяти и правильная очистка ссылок

Сохранение ссылок на закрытые формы в переменных — распространенная причина утечек памяти (Memory Leak) на стороне клиента. Объект формы продолжает удерживать свой контекст и занимать ресурсы оперативной памяти.

Посмотрим на пример правильного завершения работы с переменной формы при классическом подходе:


ФормаСерии = ПолучитьФорму("ФормаСерии");
ФормаСерии.ВладелецФормы = ЭтаФорма;
ФормаСерии.ОткрытьМодально();

// Получаем необходимые данные из формы
ЗначениеСрока = ФормаСерии.СрокГодности;

// Явно очищаем переменную для освобождения памяти
ФормаСерии = Неопределено;

Присвоение ФормаСерии = Неопределено; обнуляет последнюю ссылку на экземпляр формы, после чего сборщик мусора платформы 1С сможет окончательно удалить объект из оперативной памяти.

Рекомендуемые способы получения данных из подчиненных форм

Использование методов ПолучитьФорму() и ОткрытьМодально() считается устаревшей практикой. В современных конфигурациях (управляемое приложение, веб-клиент, режим запрета модальных окон) считывание данных напрямую из объекта закрытой формы не рекомендуется или является технически невозможным из-за асинхронности работы вызовов.

Разберем по шагам безопасные и стандартные механизмы передачи данных из дочерней формы в форму-владелец:

  1. Механизм оповещения о выборе (ОповеститьОВыборе)

    В дочерней форме при выполнении целевого действия вызывают метод передачи данных владельцу:

    
    // В коде подчиненной формы
    СтруктураРезультата = Новый Структура;
    СтруктураРезультата.Вставить("СрокГодности", ЭтотОбъект.СрокГодности);
    
    ОповеститьОВыборе(СтруктураРезультата);
    

    Форма-владелец принимает эти данные в своем стандартном клиентском обработчике ОбработкаВыбора(РезультатВыбора, ИсточникВыбора).

  2. Использование объекта ОписаниеОповещения

    При открытии дочерней формы через ОткрытьФорму() передается специальное описание оповещения о закрытии:

    
    // В форме-владельце
    ОписаниеОповещения = Новый ОписаниеОповещения("ПослеЗакрытияФормыСерии", ЭтаФорма);
    ОткрытьФорму("Документ.ПоступлениеТоваров.Форма.ФормаСерии", , ЭтаФорма, , , , ОписаниеОповещения);
    
    // Процедура-обработчик результатов закрытия
    &НаКлиенте
    Процедура ПослеЗакрытияФормыСерии(РезультатЗакрытия, ДополнительныеПараметры) Экспорт
        Если РезультатЗакрытия <> Неопределено Тогда
            // Работаем с полученными данными
            СрокГодности = РезультатЗакрытия.СрокГодности;
        КонецЕсли;
    КонецПроцедуры
    

    В самой дочерней форме закрытие выполняется с передачей структуры данных: Закрыть(СтруктураРезультата);.

  3. Использование Временного Хранилища

    Если из формы нужно передать большой объем данных или сложную структуру, подчиненная форма помещает данные во временное хранилище на сервере, используя УникальныйИдентификатор формы-владельца. Владелец считывает данные из хранилища по адресу после получения уведомления о закрытии.

Таким образом, помните: визуальное закрытие окна в 1С лишь скрывает его от пользователя. Чтобы гарантировать корректную работу приложения и избежать утечек памяти, всегда используйте штатные асинхронные механизмы передачи данных через ОписаниеОповещения или ОповеститьОВыборе.

← На главную