Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.92/13: Рейтинг темы: голосов - 13, средняя оценка - 4.92
1 / 1 / 0
Регистрация: 25.05.2008
Сообщений: 232
1

Set Form1=Nothing в каком месте?

05.11.2009, 15:12. Показов 2451. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Нужно ли освобождать ресурсы Set Form1=Nothing и в каком событии формы Form1 это надо писать или вообще не надо?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.11.2009, 15:12
Ответы с готовыми решениями:

Сделать так чтобы Form2 появлялась ровно в том же месте где и Form1
{ Form2 form = new Form2(); form.Show(); } как сделать так чтобы Form2 появлялась...

Как сделать так чтобы Form2 появлялась ровно в том же месте где и Form1
Эту тему читал https://www.cyberforum.ru/windows-forms/thread248400.html Но ответы не помогли....

На каком месте титлы в оптимизации
Вот страница в яндексе 7 по запросу "ва52-41" -...

Запрос. На каком месте пользователь
Здравствуйте. Есть таблица users, и в ней поля id и kills. Мне нужно сделать запрос, который...

16
0 / 0 / 1
Регистрация: 19.10.2008
Сообщений: 173
05.11.2009, 15:42 2
Внутри самой формы такого писать нельзя - самоубийство она совершить не сможет, да и вообще сразу писать set Form1=nothing не стоит, тк форма может зависнуть в памяти до ближайшей перезагрузки(~2MB). Можно делать так
1. Если форма одна, то ничего делать не надо(повезло).
2. Форма открывается (и должна закрываться) из класса, причем они нах-ся в одном проекте.Пишем :
Visual Basic
1
2
3
4
5
6
7
8
9
10
'В разделе переменных класса 
Dim frmForma as Form1
 
'Перед показом формы :
Set frmForma = New Form1
Load frmForma 'Это необязательно, но я всегда пишу
 
'Убиваем форму
Unload frmForma 
set frmForma =Nothing
Рекомендую в событии Terminate формы прописать код
Visual Basic
1
Debug.Print 'Форма Form1 Жестоко убита'
чтобы котролировать, действительно ли форма уничтожена в момент Set...=Nothing или её еще что-то держит на этом свете.
(В окне Immediate Window должен появиться текст).
3. Форма, и открывающий класс(или другая форма) находятся в разных проектах.
Решается различными способами. Неохота описывать, но если надо описать, пиши.
0
1 / 1 / 0
Регистрация: 25.05.2008
Сообщений: 232
05.11.2009, 16:33  [ТС] 3
To t-80
У меня есть проект. MDI форма и куча детей.
Как правильно очищать ресурсы от форм. Если можно по-подробней для особо
одаренных ) потому что я не до конца въехал в концепцию....
и еще дополнительный вопрос
И вообще нужно ли чистить ресурсы в процедурах от созданных в них объектов, типа Recordset, Контролы и тд., то что создается Set=...
Заранее благодарен.
0
0 / 0 / 1
Регистрация: 19.10.2008
Сообщений: 173
05.11.2009, 17:17 4
Да, все что Set=..., должно быть Set ...=Nothing, но объекты, типа Recordset(Connection итп) ДОЛЖНЫ быть предварительно закрыты, а формы Unload!
Подробней скажу только в понедельник, если еще надо будет.
Напиши, что конкретно непонятно(Если все непонятно, то тоже напиши), или пиши мне прямо на Email: t-80@Mail.ru
0
Vita
05.11.2009, 18:41 5
Для t-80:
Set obj = Nothing означает только то, что больше к объекту нельзя обратиться через переменную obj. И только. Не нужно думать, что произойдет что-то фатальное. И без тебя есть кому держать форму 'при жизни' (пользуясь твоей терминологией).

Для DjinnWalker:
Form1 - это не ресурс. Его освобождать не нужно. Тем более MDI. Закрытие формы через [Х] или другим легальным способом завершения формы приведет к освобождению тех ресурсов, которые занимает эта форма. Ничего дополнительного предпринимать не надо.

Освобождение переменных через Set xxx = Nothing делается для того, чтобы не удерживать объект в переменной в ФИКСИРОВАННЫЙ момент времени, т.е. именно сейчас. Однако нужно отдавать отчет, что никакого отношения к освобождениям ресурсов этот оператор не имеет, т.к. освобождаемый объект может быть задействован где-то еще. Просто именно для переменной obj объект прекратил существование.

Точно так же происходит освобождение объектов при выходе объектов из зоны видимости. Например, освобождение локальных объектных переменных в функции или процедуре при выходе из нее.
pl
51 / 17 / 6
Регистрация: 18.05.2007
Сообщений: 1,322
06.11.2009, 12:16 6
Добавлю к поледнему сообщению: Set ... = Nothing уменьшает счетчик ссылок на объект на 1. Ресурсы же объекта освобождает непоню какой менеджер. Так что если н объект несколько ссылок, то Set ... = Nothing вовсе не уничтожит его. Для этого нужно отследить все ссылки на объект и уничтожить их, только при количестве ссылок на объект = 0 он со временем уничтожится, но не сразу.
0
1 / 1 / 0
Регистрация: 25.05.2008
Сообщений: 232
06.11.2009, 19:35  [ТС] 7
Вот тебе раз... так кому верить?
Просто в учебных пособиях обычно пишут после использования
ADO объектов if rs.adStateOpen then rs.close
set rs = NOthing.
Так а как тогда чистить ресурсы в принципе? Какие нибудь может быть общие правила? Или после выхода из процедуры все объектные переменные будут уничтожены сборщиком мусора, так получается?
Может какие нибудь ссылки на эту тему кто кинет.
0
1 / 1 / 0
Регистрация: 25.08.2009
Сообщений: 79
07.11.2009, 13:33 8
P.S. А что вообще-то относится к ресурасм ????
Может тогда круг вопроса сузится ???
0
1 / 1 / 0
Регистрация: 25.05.2008
Сообщений: 232
07.11.2009, 22:24  [ТС] 9
не ресурсы а объектные переменные, скажем так.
0
Hover
07.11.2009, 22:42 10
Чтобы объект исчез из памяти компьютера, если не ошибаюсь, нужно использовать Unload(объект), во всеком случае формы и контролы точно можно бить именно так, на счет классов не помню. Форма исчезает из системы в 100% случаев только если эта форма была запускаемым объектом, если стартовой формой была другая форма, или Sub Main, то выгрузится ли форма из системы, после клика по крестику еще не известно. Поправьте меня если я ошибаюсь.
0 / 0 / 1
Регистрация: 19.10.2008
Сообщений: 173
08.11.2009, 10:28 11
Ого! А я подумал, что тема никому не нужна.
Для DjinnWalker:
Правы все, только об одно и том же говорят разными словами, основываясь, прежде всего, на своём опыте и знаниях(ну и я, разумеется).
'Закрытие формы через [Х] или другим легальным способом завершения формы приведет к освобождению тех ресурсов, которые занимает эта форма' - справедливо, но не всегда. Если форма Show из кода другой формы или класса, то, всё таки надо делать ей и Unload. К тому же, если в форме будет создана объектная переменная (Set A=New MyClass), а в событии формы QueryUnload(или другом месте, отрабатывающем закрытие формы) не будет Set A=Nothing, то даже после Unload, форма все равно будет в памяти(проверено не раз), причем закрыть ее теперь сможет только среда VB. Именно сможет(а сможет ли?). Кстати кнопка 'Стоп' в VB обладает большей мощью(в данном контексте), чем простое завершение программы. По-видимому по её нажатию VB просто уничтожает все данные, которые созданы программой. Я сталкивался даже с тем, что после закрытия среды VB, в ОЗУ оставался висеть VB6.exe метров на 90 (и только диспетчер задач поможет). Все вышесказанное так же справедливо, если в одном классе ты создашь экземпляр другого класса, а потом переменной первого класса =Nothing.
Сборщик мусора VB, вещь хорошая, только требует к себе нежного, трепетного отношения. Предположим, объявлена переменная ADODB.RecordSet внутри процедуры. Далее ...Set = New ADO..., затем .Open('Select ...), а при завершении процедуры мы ничего не делаем. Что произойдет? Наша переменная, разумеется, будет очищена из памяти, но , тк Set ..= Nothing не было, то счетчик ссылок на класс не уменьшится на один, а переменную с ссылкой мы потеряли(после Sub End). Если я не прав, то стукните по монитору мышом три раза, только не разбейте.
Если открывать форму просто как
Visual Basic
1
2
3
4
Load Form1
Form1.Show 
...
Unload Form1
, то Set Form1=Nothing, выполнит примерно тоже что и Set Integer=Nothing, так как такая запись бессмысленна.
НО !!! Я напомню, человек озабочен работой с MDI. А посему продолжим.
Я так предполагаю, что стоит задача показа одного и того же окна многократно внутри MDI, естественно не модально. А иначе зачем MDI?!
Тогда все завит от твоей концепции проекта. Предположим , что каждой видимой форме соответствует класс, который ей управляет (классы собраны напр. в массив или в коллекцию), тогда обязательно(!) должна быть переменная класса примерно следующего вида:
Visual Basic
1
Dim myForm as Form1 'Можно и WithEvents
, перед показом формы пишем
Visual Basic
1
Set myForm=New Form1
и дальше с формой Form1 работаем только через переменную myForm
По нажатию [X] поднимется событие формы (по-моему QueryUnload), в котором надо запустить метод уничтожения формы в классе, желательно все это делать через события формы, а в классе их обрабатывать. Уничтожаем форму в классе так (После того как закрыли и подчистили все объектные переменные формы!!!):
Visual Basic
1
2
  Unload myForm
  Set myForm=Nothing 'Имеет смысл тк было Set =New
Это, конечно, только рекомендация, один из вариантов, как можно делать. Проект, построенный по такой схеме работает и весьма надежно.

Для всех: Если я ошибаюсь или заблуждаюсь(что хуже) поправьте, буду благодарен. Опишите для DjinnWalker как у вас организована работа в MDI, если таковой опыт имеется, я думаю это будет всем интересно.
0
0 / 0 / 1
Регистрация: 19.10.2008
Сообщений: 173
08.11.2009, 10:43 12
PS:
Когда счетчик ссылок на класс становится равным 0, то перед тем как экземпляр класса будет уничтожен из памяти, будет поднято событие Terminate класса. Воспользуйся этим для контроля, реально ли экземпляр класса выгрузился из памяти (или форма, если работаешь с ней через переменную).
Настоятельно рекомендую.
0
1 / 1 / 0
Регистрация: 25.05.2008
Сообщений: 232
08.11.2009, 13:25  [ТС] 13
Таким образом, все мои формы создавать через объектную переменную:
Dim myFrmOne=new frmOne

и работать с myFrmOne. Я правильно понимаю?
Да кстати, если кто работат с MDI проектами, поделитесь опытом как у вас организована работа с детьми и тд.
Всем благодарен!
0
Vita
08.11.2009, 15:56 14
Для t-80:
Цитата: Set Form1=Nothing, выполнит примерно тоже что и Set Integer=Nothing, так как такая запись бессмысленна.
Ответ: На самом деле она не бессмыленна по синтаксису, но бессмысленна по сути или семантике. Вот примеры. Для обычной формы
Visual Basic
1
2
3
4
5
6
Private Sub Form_Click()
  Form1.Caption = 'xxxx'
  Debug.Print 'Before', Form1.Name, Form1.Caption
  Set Form1 = Nothing
  Debug.Print 'After', Form1.Name, Form1.Caption, Forms.Count
End Sub
Или для MDI
Visual Basic
1
2
3
4
5
6
Private Sub MDIForm_Click()
  Form1.Caption = 'xxxx'
  Debug.Print 'Before', Form1.Name, Form1.Caption
  Set Form1 = Nothing
  Debug.Print 'After', Form1.Name, Form1.Caption, Forms.Count
End Sub
Очевидно, что Form1 - это и имя класса формы, и имя какой-то переменной с достаточно сложным объявлением. Примерно с таким: Dim Form1 As New Form1.

PS. Но больший эффект несет то, что Forms.Count все время будет увеличиваться. Также поведение вышеуказанных примеров различно - SDI зависает, а вот MDI уже нет.
Vita
08.11.2009, 16:24 15
Для DjinnWalker:
Visual Basic
1
2
3
Private Sub MDIForm_Click()
  Load New Form1
End Sub
Работает прекрасно - загружается каждый раз новое окно. В конструкторе (в Form_Initialize или Form_Load, кому как нравится) делаешь необходимую подготовительную работу. В деструкторе (в Form_Terminate или Form_Unload) делаешь заключительную. Но заметь нет никаких Set Form1 = Nothing и т.п.

Но, как правило, порождающий код должен что-то добавить от себя. Поэтому и вводится ЛОКАЛЬНАЯ переменная
Visual Basic
1
2
3
4
5
6
Private Sub MDIForm_Click()
  Dim frm As Form1
  Set frm = New Form1
  frm.Caption = '....'
  frm.Show ' это можно и не делать
End Sub
Или без переменной
Visual Basic
1
2
3
4
5
6
Private Sub MDIForm_Click()
  With New Form1
    .Caption = '....'
    .Show ' это можно и не делать
  End with
End Sub
Все твои формы аккумулируются в коллекции Forms, так что хранить их где-либо становится не нужным.
0 / 0 / 1
Регистрация: 19.10.2008
Сообщений: 173
08.11.2009, 17:11 16
to Vita:
Так не пробовал, но результат экспериментов объясним, так как в первом случае(для SDI)
Visual Basic
1
2
Set Form1 = Nothing 
Debug.Print 'After', Form1.Name, Form1.Caption, Forms.Count
При выполнении второй строки VB не знает что такое Form1, она для него Nothing, он должен бы выдать что-нибудь вроде 'Хочу Объект', но скорее всего у него просто сносит башню(Sorry за franch), так как он нах-ся внутри Nothing'a(что-то типа того).
А в случае с MDI, если что-то и происходит при Set Form1=Nothing, то при обращении Form1.Name VB самостоятельно выполнит Load Form1(потому и не виснет). Возможно так.
И вопрос, что VB автоматом создает коллекцию из форм , добавляя элемент при каждом Load Form1? А обращаться Form1.Item(i)? А как удалять? Можно ли использовать при Form1.Item() строковый ключ? (На грамма сарказма, я этого просто не знаю, а интересно)

to DjinnWalker:
Когда будешь прорабатывать работу с детьми, то избавишь себя от головной боли, если учтешь такой момент:
Свободных окон, порожденных непосредственно от MDI, или главного класса, должно быть минимум, а лучше одно. Тогда отладив один раз работу MDI, тебе никогда не придется лезть в его код при добавлении второстепенных окон.
Каждое окно/класс среди прочих свойств должно иметь набор ссылок (например в виде коллекции) для детей, и ссылку на родителя(если в родителе переменная с ссылкой на класс/окно объявлена с WithEvents, то необязательно). Так же любой класс должен 'знать' только о своих детях и своего родителя(не обязат., см выше).
Закрытие окна при этом происходит так:
1. Нажали [X], либо получена команда от родителя на закрытие.
2. Послать команду на закрытие всем своим детям.
3. При подтверждении каждого ребенка готовности к закрытию, сделать ему Unload(если форма) и Nothing.
4. Подчистить все свои объектные переменные.
5. Послать родителю подтверждение на собственное уничтожение (либо отказ от него).
Такой алгоритм прописать одинаковым для всех классов/окон в иерархии, и забыть о нем навсегда.
0
0 / 0 / 1
Регистрация: 19.10.2008
Сообщений: 173
08.11.2009, 17:22 17
PS
to Vita:
Извиняюсь, не видел твоего последнего сообщения.
Все понятно. Просто разный стиль программирования.
0
08.11.2009, 17:22
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.11.2009, 17:22
Помогаю со студенческими работами здесь

В каком месте программы описывается структура
подскажите пожалуйста в каком месте программы описывается структура???

В каком месте документа HTML вставлять JS
Вставляю, как и рекомендуется в <head>. Но валидатор ошибок говорит, что это место не предназначено...

в каком месте правильнее объявлять переменную?
Давно мучит вопрос, в каком месте правильнее объявлять переменную? в варианте №1 или №2? №1. ...

Узнать в каком месте выполняется код
Возможно ли как-то узнать, где конкретно в данный момент висит программа? Точка останова не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru