Форум: "Начинающим";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];
ВнизНе уничтожается объект Найти похожие ветки
← →
Константин (2010-03-22 15:47) [0]Допустим у нас есть у объекта Object1 поле типа TObject2 и ObjеctList с объектами TObject2 который ими владеет.
В креате Object1 полю Object2 присваивается nil.
В какой то момент я присваиваю этому полю ссылку на объект из ObjеctList
Object1.Object2 := ObjеctList[i];
и потом в какой то момент делаю ObjеctList.Delete[i], но судя по дебаггеру в поле Object1.Object2 этот объект присутствует и Object2 не равен nil. Почему так происходит?
← →
И. Павел © (2010-03-22 15:53) [1]Кажется это уже обсуждалось пару дней назад.
Object1.Object2 ничего не знает об удаление объекта. Он продолжает хранить адрес. Когда уничтожаете объект - устанавливайте все ссылки на него в nil.
← →
Anatoly Podgoretsky © (2010-03-22 15:53) [2]> Константин (22.03.2010 15:47:00) [0]
А ты что нибудь сделал для этого?
← →
Anatoly Podgoretsky © (2010-03-22 15:54) [3]
> Когда уничтожаете объект - устанавливайте все ссылки на
> него в nil.
Для этого заводи еще несколько ObjеctList :-)
← →
К (2010-03-22 16:43) [4]
> Anatoly Podgoretsky © (22.03.10 15:54) [3]
не, я делаю overload у TList.Delete где нахожу все ссылки и ставлю им nil ;)
Я просто не особо пойму что такое nil. Тобишь когда TObjectList сделал Free, объект освободил память, а указатель остался? Вернее получается что в TObjectList происходит сдвиг и фактически этот указатель указывает на уже другой объект, если в TObjectList было больше двух объектов?
← →
И. Павел © (2010-03-22 16:52) [5]
A:=TA.Create;
A:=B;
B.Free;
После этого и A и B все еще будут ссылаться на участок памяти, где раньше был объект. B.Free - это не очищение B, это удаление объекта, на который ссыллается B. Для того, чтобы очистить B нужно написать B:=nil.
← →
И. Павел © (2010-03-22 16:52) [6]A:=B; -> B:=A;
← →
Инопланетянин (2010-03-22 17:38) [7]> К (22.03.10 16:43) [4]
Я создал объект и завел на него сто ссылок. Или тыщу. Или миллион. Знает ли объект об этих ссылках?
Нет, сам по себе не знает. И никакой другой объект в моей программе об этих ссылках тоже сам по себе не знает. Даже TObjectList, если я включу в него этот объект, знает только об одной (своей внутренней) ссылке, а про остальные 999999 ему ничего неизвестно.
Теперь я уничтожил этот объект. Может ли он в своем деструкторе сам очистить все ссылки на себя?
Нет, не может - ведь он ни о каких ссылках ничего не знает.
Тогда я стал уничтожать объект не напрямую, а чарез TObjectList. Догадываетесь, что происходит?
Правильно - одна ссылка (внутренняя в TObjectList) исчезает из списка, а с остальными ссылками НЕ ПРОИСХОДИТ НИЧЕГО. Они как были, так и остались. Да и с чего бы им меняться, если их никто не менял?
Обо ВСЕХ ссылках на объект в своей программе знает только ПРОГРАММИСТ. Поэтому только он один может (и должен!) написать код, который все эти ссылки очистит (то есть, присвоит им nil).
← →
oldman © (2010-03-22 17:49) [8]
> Почему так происходит?
то есть, рисовать на бумажке блок-схему алгоритма и думать нам лень?
← →
Константин (2010-03-22 18:03) [9]
> И. Павел © (22.03.10 16:52) [5]
тобишь надо? правильно?
destructor TB.Destroy; override;
begin
A := nil;
end;
> Инопланетянин (22.03.10 17:38) [7]
То есть когда обджек лист освобождает объект он не смещает указатели?
← →
Медвежонок Пятачок © (2010-03-22 18:08) [10]А при чем здесь лист и его смещения, если ссылка осталась и сидит в Object1.Object2 ?
← →
И. Павел © (2010-03-22 18:25) [11]
> тобишь надо? правильно?
ИМХО не совсем. В приведенном мною примере работать будет. Но вы же можете создать несколько объектов TB: B1, B2, B3. И соответствующие им: A1, A2, A3.
Как пример:
Все ссылки могут храниться в одном ObjectList. Можно сравнивать известную ссылку на объект, который хотим удалить, со всеми остальными - если две ссылки равны - значит они ссылаются на один и тот же объект (если тип один и тот же). Удаляем объект, а всем этим ссылкам присваиваем nil.
← →
Anatoly Podgoretsky © (2010-03-22 19:24) [12]> К (22.03.2010 16:43:04) [4]
Ты что сканируешь память на физическом уровне?
← →
Anatoly Podgoretsky © (2010-03-22 19:24) [13]> Константин (22.03.2010 18:03:09) [9]
А В, а С забыл, а в других модуляхне?
← →
Константин (2010-03-22 20:22) [14]ну я так понимаю мне надо хранить ссылки на объекты, которые ссылаются на удаляемый (в нём хранить) и деструкторе им присваивать nil
Думаю это будет нормальный способ.
Может есть какой-то другой? как то через интерфейс или типа того?
← →
Дмитрий Белькевич (2010-03-23 11:14) [15]
> Можно сравнивать известную ссылку на объект, который хотим
> удалить, со всеми остальными - если две ссылки равны - значит
> они ссылаются на один и тот же объект (если тип один и тот
> же)
Тип - пофиг. Если адреса ссылок равны - то и ссылки равны.
> Может есть какой-то другой? как то через интерфейс или типа
> того?
Задачу расскажи, чего нужно. Пока что какие-то туманные телодвижения с объектами.
> Обо ВСЕХ ссылках на объект в своей программе знает только
> ПРОГРАММИСТ. Поэтому только он один может (и должен!) написать
> код, который все эти ссылки очистит (то есть, присвоит им
> nil).
А по хорошему, хранить только одну ссылку. Так обычно надёжнее и меньше возни с очисткой дохлых ссылок.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.06 c