вторник, 24 сентября 2013 г.

И ещё о собственных фреймворках

Тут не раз звучал вопрос - "а зачем собственные фреймворки?"

Нарисовался вот ещё такой пример.

Пусть есть объект VCL. Контрол.

Пусть у него есть обработчик OnClick.

Пусть в этом OnClick выполняются какие-то действия.

И всё хорошо. До тех пор пока в OnClick не делается что-то такое, что опосредованно приводит к убиению контрола. Например контрол вызывает смену прецедента, которая, в свою очередь, вызывает смену текущей формы с её убиванием.

Итак - новая форма появилась. Старая - убилась. Вместе с ней - убился и контрол.

А потом, о ужас! Начинается возврат по стеку. И в итоге попадаем в исходные метод контрола, который вызвал OnClick. А контрол - УЖЕ убит. И тут начинаются варианты - либо "повезёт" и просто так "проедемся по памяти", либо AV, либо abstract error ну и т.п.

Так вот наш фреймворк даёт гарантию, что такого не произойдёт. Ну если соблюдать нехитрые правила.

Грубо говоря - в коде контрола, который вызывает обработчик зовутся пары методов afw.KeepObject(Self)/afw.UnkeepObject(Self), а destroy и FreeInstance контролов устроены таким образом, что не разрушают объект внутри этих скобок. Только ВНЕ их.

Если находится ВНЕШНИЙ проблемный код, то эти скобки ставятся и в нём.


Нет, я конечно знаю про Release. Но этот метод мало что гарантирует. Достаточно где-нибудь внутри обработчика случиться вызову Application.ProcessMessages и сразу появляется ненулевая вероятность получить приложение в нестабильном состоянии.

15 комментариев:

  1. "ненулевая вероятность"
    хорошее словосочетание, добавлю в свой словарный запас ))

    ОтветитьУдалить
    Ответы
    1. "ненулевая вероятность"

      ну это же - правда :-)

      Удалить
    2. Это выражение - опять же не я придумал... Оно регулярно использовалось преподавателями во всяких дисциплинах типа "устойчивости систем" :-)

      Удалить
    3. http://ru.wikipedia.org/wiki/%D0%9A%D0%B2%D0%B0%D0%BD%D1%82%D0%BE%D0%B2%D0%BE%D0%B5_%D0%B1%D0%B5%D1%81%D1%81%D0%BC%D0%B5%D1%80%D1%82%D0%B8%D0%B5

      Удалить
    4. http://alexandr4784.narod.ru/B16/b16_3_33.pdf

      Удалить
  2. «Грубо говоря - в коде контрола, который вызывает обработчик зовутся пары методов afw.KeepObject(Self)/afw.UnkeepObject(Self), а destroy и FreeInstance контролов устроены таким образом, что не разрушают объект внутри этих скобок. Только ВНЕ их.»
    -- Вы не могли бы привести примеры Destroy и FreeInstance таких элементов управления?
    Есть опасения, что у потомков таких классов (с перекрытыми Destroy и FreeInstance) будут проблемы с Вашими "скобками", если, разумеется, не предпринять соответствующих действий в Destroy этих потомков.

    ОтветитьУдалить
    Ответы
    1. Да вы правы насчёт деструктора и FreeInstance. Тут есть определённые правила. В классе вводится метод Cleanup, который и должны перекрывать потомки. А деструктор и FreeInstance делаются sealed (final). Как это делается в Delphi 7 я писал тут - http://18delphi.blogspot.ru/2013/03/blog-post_4606.html и тут - http://18delphi.blogspot.ru/2013/03/blog-post_4606.html?showComment=1365451359891#c3861869522579730123

      Удалить
  3. «Тут есть определённые правила. В классе вводится метод Cleanup, который и должны перекрывать потомки. А деструктор и FreeInstance делаются sealed (final).»
    -- Техника понятна. Спасибо.

    «До тех пор пока в OnClick не делается что-то такое, что опосредованно приводит к убиению контрола. Например контрол вызывает смену прецедента, которая, в свою очередь, вызывает смену текущей формы с её убиванием.»
    -- Не проще ли было предпринять соответствующие действия на этом уровне?
    IMHO это весьма специфичная ситуация, когда форма удаляется в контексте обработчиков своих событий (или обработчиков событий своих компонентов). Например, можно подумать об отложенном закрытии формы вне контекста ProcessMessages.

    ОтветитьУдалить
    Ответы
    1. "Например, можно подумать об отложенном закрытии формы вне контекста ProcessMessages."
      -- уже подумано и не раз... и реализовано.. тоже..

      Удалить
    2. "IMHO это весьма специфичная ситуация, когда форма удаляется в контексте обработчиков своих событий (или обработчиков событий своих компонентов)"

      -- это вам так кажется...

      Удалить
    3. Я вот только ОДНОГО не понимаю.. Если честно.. У меня есть success-story.. И не одна.. Вы не путаете меня со своими студентами? Если вам РЕАЛЬНО интересно, то наверное вопросы стоит как-то "мяхше" задавать...

      Удалить
  4. «Если вам РЕАЛЬНО интересно, то наверное вопросы стоит как-то "мяхше" задавать...»
    -- Александр, а где Вы увидели грубость? 8-O
    Собственно, в этой части уже не особенно интересно, выше Вы ответили по-существу.
    Другая известная мне success story основана на принципах, которые я обозначил в том, что Вы прокомментировали "не проще" и "мне показалось". - Не показалось... :-)

    ОтветитьУдалить
    Ответы
    1. Прошу прощения за оффтоп.
      Не мое, конечно, дело, но должен выразить восхищение терпением Александра.
      "Опишите Y, опишите X - в таком виде это будет представлять интерес". Пардон, уважаемый NameRec, но с каких это шишей вдруг Вы решили, что Вы имеете какое-то моральное право хоть кому-то в этой жизни указывать, что будет представлять интерес (и для кого, собственно - для Вас?), а что - нет?
      Или это: "Именно так. Необязательно сочинять здесь ВойнуИМир :-) Нужно указать просто, как технологически выглядит процесс добавления новой настройки". Ой! "Войну и мир" сочинять необязательно? Ой спасибо, ой утешили. Да что б мы без вас, да как бы мы без вас!
      Мне одному показалось, что студент Александр Люлин написал курсовик и принес показать оный преподавателю на кафедру, который тут же со значимым видом стал возюкать пальцем по тексту и тыкать носом нерадивого студента в те места, которые не соответствуют гениальным воззрениям непризнанного светилы computer science из Усть-удойского котлостроительного института?

      Удалить
  5. Уважаемый Виктор Морозов! Если Ваши вопросы не носят риторический характер, Вы всегда можете задать их мне по электронной почте, адрес которой Вы можете найти в моём профиле.
    Действительно, зачем разводить здесь означенный Вами "оффтоп"? Тем более, мне показалось, что Александр не нуждается в "адвокатах".
    Если же Александр склонен воспринимать изложенное Вами аналогично Вам, он тоже может обратиться ко мне напрямую и совершенно без посредников. Что и делал не раз, к слову.

    ОтветитьУдалить