В обсуждении (http://18delphi.blogspot.ru/2013/04/vcl-3.html?showComment=1388007562534#c746555596336886486) дали мне ссылку на текст.
Ссылка на текст тут - http://blogs.embarcadero.com/abauer/2010/02/16/38916
Я РЕАЛЬНО НЕ ПОНЯЛ ни ОДНОГО ПРЕДЛОЖЕНИЯ. Проблема у меня в ДНК? Или в тексте?
Может быть кто-нибудь расскажет мне о том - "что там написано"? ОГРОМНОЕ ПОЖАЛУЙСТА! (Ну не хочется "быть идиотом" и "отставать от мейнстрима").
Текст:
"It seems that my previous post about FreeAndNil sparked a little controversy. Some of you jumped right on board and flat agreed with my assertion. Others took a very defensive approach. Still others, kept an “arms-length” view. Actually, the whole discussion in the comments was very enjoyable to read. There were some very excellent cases on both sides. Whether or not you agreed with my assertion, it was very clear that an example of why I felt the need to make that post was in order.
I wanted to include an example in my first draft of the original post, but I felt that it would come across as too contrived. This time, instead of including some contrived hunk of code that only serves to cloud the issue at hand, I’m going to try a narrative approach and let the reader decide if this is something they need to consider. I may fall flat on my face with this, but I want to try and be as descriptive as I can without the code itself getting in the way. It’s an experiment. Since many of my readers are, presumably, Delphi or C++Builder developers and have some working knowledge of the VCL framework, I will try and present some of the problems and potential solutions in terms of the services that VCL provides.
To start off, the most common case I’ve seen where FreeAndNil can lead to strange behaviors or even memory leaks is when you have a component with a object reference field that is allocated “lazily.” What I mean is that you decide you don’t need burn the memory this object takes up all the time so you leave the field nil and don’t create the instance in the constructor. You rely on the fact that it is nil to know that you need to allocate it. This may seem like the perfect case where you should use FreeAndNil! That is in-fact the very problem. There are cases where you should FreeAndNil in this scenario. The scenario I’m about to describe is not such a case.
If you recall from the previous post, I was specifically referring to using FreeAndNil in the destructor. This is where a very careful dance has to happen. A common scenario in VCL code is to hold references to other component from a given component. Because you are holding a reference there is a built-in mechanism that allows you coordinate the interactions between the components by knowing when a given component is being destroyed. There is the Notification virtual method you can override to know if the component being destroyed is the one to which you have a reference. The general pattern here is to simply nil out your reference.
The problem comes in when you decide that you need to grab some more information out of the object while it is in the throes of destruction. This is where things get dangerous. Just the act of referencing the instance can have dire consequences. Where this can actually cause a memory leak was if the field, property, or method accessed caused the object to lazily allocate that instance I just talked about above. What if the code to destroy that instance was already run in the destructor by the time the Notification method was called? Now you’ve just allocated an instance which has no way to be freed. It’s a leak. It’s also a case where a nil field will never actually cause a crash because you were sooo careful to check for nil and allocate the field if needed. You’ve traded a crash for a memory leak. I’ll let you decide whether or not that is right for your case. My opinion is that leak or crash, it is simply not good design to access an instance that is in the process of being destroyed.
“Oh, I never do that!” That’s probably true, however what about the user’s of your component? Do they understand the internal workings of your component and know that accessing the instance while it is in the throes of destruction is bad? What if it “worked” in v1 of your component and v2 changed some of the internals? Do they even know that the the instance is being destroyed? Luckily, VCL has provided a solution to this by way of the ComponentState. Before the destructor is called that starts the whole destruction process, the virtual method, BeforeDestruction is called which sets the csDestroying flag. This can now be used as a cue for any given component instance whether or not it is being destroyed.
While my post indicting FreeAndNil as not being your friend may have come across as a blanket statement decrying its wanton use, I was clearly not articulating as well as I should that blindly using FreeAndNil without understanding the consequences of its effect on the system as a whole, is likely to bite you. My above example is but one case where you should be very careful about accessing an object in the process of destruction. My point was that using FreeAndNil can sometimes appear to solve the actual problem, when in fact if has merely traded it for another, more insidious, hard to find problem. A problem that doesn’t bite immediately."
Самое что смешное, что я САМ перевёл его примерно так же как и автоматический переводчик:
"Кажется, что мой предыдущий пост о FreeAndNil вызвало небольшой спор. Некоторые из вас прыгнул прямо на борту и помещения согласился с моим утверждением. Другие взяли очень оборонительный подход. Третьи, бдительно "руки длины" вид. На самом деле, вся дискуссия в комментариях было очень приятно читать. Были некоторые очень отличные случаи с обеих сторон. Или вы не согласился с моим утверждением, это было очень ясно, что пример того, почему я чувствовал необходимость сделать этот пост было в порядке.
Я хотел включить пример в моем первом проекте исходное сообщение, но я чувствовал, что это было бы встретить, как слишком надуманный. На этот раз, вместо того, чтобы в том числе некоторые надуманный кусок кода, который только служит для облачных вопрос под рукой, я собираюсь попробовать повествовательный подход и пусть читатель решить, если это то, что они должны рассмотреть. Я может не иметь успеха на моем лице с этим, но я хочу попробовать и быть максимально информативным могу без кода сам получать в пути. Это эксперимент. Так как многие из моих читателей, надо полагать, Delphi или C + + разработчики Builder и есть практическое знание рамках VCL, я постараюсь и представить некоторые из проблем и потенциальных решений с точки зрения услуг, которые предоставляет VCL.
Для начала, самый распространенный случай я видел, где FreeAndNil может привести к странного поведения или даже утечек памяти, когда у вас есть компонент с опорным полем объекта, который выделяется "лениво". Я имею в виду, что вы решите вы не 'т нужно сжечь память этот объект принимает все время, так что вы оставьте поле ноль и не создают экземпляр в конструкторе. Вы полагаться на то, что это ноль, чтобы знать, что вам нужно передать его. Это может показаться идеальным случае, когда вы должны использовать FreeAndNil! То есть в-то, сама проблема. Есть случаи, когда вы должны FreeAndNil в этом сценарии. Сценарий, который я собираюсь описать не такой случай.
Если вы помните из предыдущего поста, я, непосредственно относящиеся к использованию FreeAndNil в деструкторе. Это где очень осторожны танец должно произойти. Обычный сценарий в VCL код провести упоминание другого компонента из данного компонента. Потому что вы держите ссылку существует встроенный механизм, который позволяет координировать взаимодействие между компонентами, зная, когда данный компонент разрушается. Существует Уведомление виртуальный метод можно переопределить, чтобы узнать, если компонент разрушается является тот, на который у вас есть ссылка. Общая картина здесь, чтобы просто ноль ваш ссылку.
Проблема возникает, когда вы решите, что вам нужно, чтобы захватить еще немного информации из объекта пока он находится в муках уничтожения. Это где все становится опасно. Сам факт того, чтобы представить экземпляр может иметь ужасные последствия. Там, где это может вызвать утечка памяти был, если поле, свойство или метод доступны вызвало объект, лениво выделить этот экземпляр я просто говорил о выше. Что делать, если код, уничтожить этот экземпляр уже запущен в деструкторе к тому времени, метод Уведомление назывался? Теперь вы только что выделил экземпляр, который не имеет никакой возможности, чтобы освободиться. Это утечка. Это также случай, когда ноль поле никогда не будет на самом деле привести к аварии, потому что вы были так осторожны, чтобы проверить на ноль и выделить поле, если это необходимо. Вы торгуются обвал на утечки памяти. Я дам вам решить, является ли, что подходит для вашего случая. Мое мнение, что утечка или авария, это просто не хороший дизайн, чтобы получить доступ к экземпляру, который находится в процессе уничтожения.
"О, я никогда не делайте этого!" Это, вероятно, справедливо, однако, что о пользователя вашего компонента? Понимают ли они внутренней работы вашего компонента и знать, что доступ к экземпляр пока он находится в муках уничтожения плохо? Что, если это «работал» в v1 вашего компонента и v2 изменили некоторые из внутренних? Они даже не знают, что экземпляр разрушается? К счастью, VCL предоставил решение этого по пути ComponentState. Перед вызывается деструктор, который начинается весь процесс уничтожения, виртуальный метод, BeforeDestruction называется устанавливающего флаг csDestroying. Это теперь можно использовать как сигнал для любого экземпляра данного компонента является ли оно разрушается.
В то время как мой пост обвинении FreeAndNil как не ваш друг, возможно, встретить, как одеяло заявления осуждают его бессмысленное использование, я был явно не артикулировать, а также я должен, что слепо помощью FreeAndNil не понимая последствий его влияния на систему в целом , скорее всего, чтобы укусить вас. Мой выше пример является лишь одним случаем, когда вы должны быть очень осторожны в обращении объект в процессе уничтожения. Моя точка зрения в том, что с помощью FreeAndNil может иногда появляются решить актуальную проблему, когда на самом деле, если уже просто обменял его на другой, более коварная, трудно найти проблему. Проблема, которая не кусается сразу."
P.S. как выясняется - Я НЕ ОДИН такой....
P.P.S.
lulinalex: http://programmingmindstream.blogspot.ru/2013/12/blog-post_3160.html
XXX: Забей это у автора не то с генами
lulinalex: да?! :-) я СЧАСТЛИВ!! :-) СПАСИБО!!!
XXX: Его в комментах вежливо умыли что лучше огрести ав из за nil чем проезд по памяти из за записи в убитый объект
lulinalex: :-)
lulinalex: о чём gunsmoker и писал...
XXX: Он согласился хотя топик не снес
P.P.P.S. Не знаю уж кто такой "abauer" и чем он так "уважаем", но моё "уважение" к нему - ПОДОРВАНО... Раз (и думаю) - НАВСЕГДА...
Ссылка на текст тут - http://blogs.embarcadero.com/abauer/2010/02/16/38916
Я РЕАЛЬНО НЕ ПОНЯЛ ни ОДНОГО ПРЕДЛОЖЕНИЯ. Проблема у меня в ДНК? Или в тексте?
Может быть кто-нибудь расскажет мне о том - "что там написано"? ОГРОМНОЕ ПОЖАЛУЙСТА! (Ну не хочется "быть идиотом" и "отставать от мейнстрима").
Текст:
"It seems that my previous post about FreeAndNil sparked a little controversy. Some of you jumped right on board and flat agreed with my assertion. Others took a very defensive approach. Still others, kept an “arms-length” view. Actually, the whole discussion in the comments was very enjoyable to read. There were some very excellent cases on both sides. Whether or not you agreed with my assertion, it was very clear that an example of why I felt the need to make that post was in order.
I wanted to include an example in my first draft of the original post, but I felt that it would come across as too contrived. This time, instead of including some contrived hunk of code that only serves to cloud the issue at hand, I’m going to try a narrative approach and let the reader decide if this is something they need to consider. I may fall flat on my face with this, but I want to try and be as descriptive as I can without the code itself getting in the way. It’s an experiment. Since many of my readers are, presumably, Delphi or C++Builder developers and have some working knowledge of the VCL framework, I will try and present some of the problems and potential solutions in terms of the services that VCL provides.
To start off, the most common case I’ve seen where FreeAndNil can lead to strange behaviors or even memory leaks is when you have a component with a object reference field that is allocated “lazily.” What I mean is that you decide you don’t need burn the memory this object takes up all the time so you leave the field nil and don’t create the instance in the constructor. You rely on the fact that it is nil to know that you need to allocate it. This may seem like the perfect case where you should use FreeAndNil! That is in-fact the very problem. There are cases where you should FreeAndNil in this scenario. The scenario I’m about to describe is not such a case.
If you recall from the previous post, I was specifically referring to using FreeAndNil in the destructor. This is where a very careful dance has to happen. A common scenario in VCL code is to hold references to other component from a given component. Because you are holding a reference there is a built-in mechanism that allows you coordinate the interactions between the components by knowing when a given component is being destroyed. There is the Notification virtual method you can override to know if the component being destroyed is the one to which you have a reference. The general pattern here is to simply nil out your reference.
The problem comes in when you decide that you need to grab some more information out of the object while it is in the throes of destruction. This is where things get dangerous. Just the act of referencing the instance can have dire consequences. Where this can actually cause a memory leak was if the field, property, or method accessed caused the object to lazily allocate that instance I just talked about above. What if the code to destroy that instance was already run in the destructor by the time the Notification method was called? Now you’ve just allocated an instance which has no way to be freed. It’s a leak. It’s also a case where a nil field will never actually cause a crash because you were sooo careful to check for nil and allocate the field if needed. You’ve traded a crash for a memory leak. I’ll let you decide whether or not that is right for your case. My opinion is that leak or crash, it is simply not good design to access an instance that is in the process of being destroyed.
“Oh, I never do that!” That’s probably true, however what about the user’s of your component? Do they understand the internal workings of your component and know that accessing the instance while it is in the throes of destruction is bad? What if it “worked” in v1 of your component and v2 changed some of the internals? Do they even know that the the instance is being destroyed? Luckily, VCL has provided a solution to this by way of the ComponentState. Before the destructor is called that starts the whole destruction process, the virtual method, BeforeDestruction is called which sets the csDestroying flag. This can now be used as a cue for any given component instance whether or not it is being destroyed.
While my post indicting FreeAndNil as not being your friend may have come across as a blanket statement decrying its wanton use, I was clearly not articulating as well as I should that blindly using FreeAndNil without understanding the consequences of its effect on the system as a whole, is likely to bite you. My above example is but one case where you should be very careful about accessing an object in the process of destruction. My point was that using FreeAndNil can sometimes appear to solve the actual problem, when in fact if has merely traded it for another, more insidious, hard to find problem. A problem that doesn’t bite immediately."
Самое что смешное, что я САМ перевёл его примерно так же как и автоматический переводчик:
"Кажется, что мой предыдущий пост о FreeAndNil вызвало небольшой спор. Некоторые из вас прыгнул прямо на борту и помещения согласился с моим утверждением. Другие взяли очень оборонительный подход. Третьи, бдительно "руки длины" вид. На самом деле, вся дискуссия в комментариях было очень приятно читать. Были некоторые очень отличные случаи с обеих сторон. Или вы не согласился с моим утверждением, это было очень ясно, что пример того, почему я чувствовал необходимость сделать этот пост было в порядке.
Я хотел включить пример в моем первом проекте исходное сообщение, но я чувствовал, что это было бы встретить, как слишком надуманный. На этот раз, вместо того, чтобы в том числе некоторые надуманный кусок кода, который только служит для облачных вопрос под рукой, я собираюсь попробовать повествовательный подход и пусть читатель решить, если это то, что они должны рассмотреть. Я может не иметь успеха на моем лице с этим, но я хочу попробовать и быть максимально информативным могу без кода сам получать в пути. Это эксперимент. Так как многие из моих читателей, надо полагать, Delphi или C + + разработчики Builder и есть практическое знание рамках VCL, я постараюсь и представить некоторые из проблем и потенциальных решений с точки зрения услуг, которые предоставляет VCL.
Для начала, самый распространенный случай я видел, где FreeAndNil может привести к странного поведения или даже утечек памяти, когда у вас есть компонент с опорным полем объекта, который выделяется "лениво". Я имею в виду, что вы решите вы не 'т нужно сжечь память этот объект принимает все время, так что вы оставьте поле ноль и не создают экземпляр в конструкторе. Вы полагаться на то, что это ноль, чтобы знать, что вам нужно передать его. Это может показаться идеальным случае, когда вы должны использовать FreeAndNil! То есть в-то, сама проблема. Есть случаи, когда вы должны FreeAndNil в этом сценарии. Сценарий, который я собираюсь описать не такой случай.
Если вы помните из предыдущего поста, я, непосредственно относящиеся к использованию FreeAndNil в деструкторе. Это где очень осторожны танец должно произойти. Обычный сценарий в VCL код провести упоминание другого компонента из данного компонента. Потому что вы держите ссылку существует встроенный механизм, который позволяет координировать взаимодействие между компонентами, зная, когда данный компонент разрушается. Существует Уведомление виртуальный метод можно переопределить, чтобы узнать, если компонент разрушается является тот, на который у вас есть ссылка. Общая картина здесь, чтобы просто ноль ваш ссылку.
Проблема возникает, когда вы решите, что вам нужно, чтобы захватить еще немного информации из объекта пока он находится в муках уничтожения. Это где все становится опасно. Сам факт того, чтобы представить экземпляр может иметь ужасные последствия. Там, где это может вызвать утечка памяти был, если поле, свойство или метод доступны вызвало объект, лениво выделить этот экземпляр я просто говорил о выше. Что делать, если код, уничтожить этот экземпляр уже запущен в деструкторе к тому времени, метод Уведомление назывался? Теперь вы только что выделил экземпляр, который не имеет никакой возможности, чтобы освободиться. Это утечка. Это также случай, когда ноль поле никогда не будет на самом деле привести к аварии, потому что вы были так осторожны, чтобы проверить на ноль и выделить поле, если это необходимо. Вы торгуются обвал на утечки памяти. Я дам вам решить, является ли, что подходит для вашего случая. Мое мнение, что утечка или авария, это просто не хороший дизайн, чтобы получить доступ к экземпляру, который находится в процессе уничтожения.
"О, я никогда не делайте этого!" Это, вероятно, справедливо, однако, что о пользователя вашего компонента? Понимают ли они внутренней работы вашего компонента и знать, что доступ к экземпляр пока он находится в муках уничтожения плохо? Что, если это «работал» в v1 вашего компонента и v2 изменили некоторые из внутренних? Они даже не знают, что экземпляр разрушается? К счастью, VCL предоставил решение этого по пути ComponentState. Перед вызывается деструктор, который начинается весь процесс уничтожения, виртуальный метод, BeforeDestruction называется устанавливающего флаг csDestroying. Это теперь можно использовать как сигнал для любого экземпляра данного компонента является ли оно разрушается.
В то время как мой пост обвинении FreeAndNil как не ваш друг, возможно, встретить, как одеяло заявления осуждают его бессмысленное использование, я был явно не артикулировать, а также я должен, что слепо помощью FreeAndNil не понимая последствий его влияния на систему в целом , скорее всего, чтобы укусить вас. Мой выше пример является лишь одним случаем, когда вы должны быть очень осторожны в обращении объект в процессе уничтожения. Моя точка зрения в том, что с помощью FreeAndNil может иногда появляются решить актуальную проблему, когда на самом деле, если уже просто обменял его на другой, более коварная, трудно найти проблему. Проблема, которая не кусается сразу."
P.S. как выясняется - Я НЕ ОДИН такой....
P.P.S.
lulinalex: http://programmingmindstream.blogspot.ru/2013/12/blog-post_3160.html
XXX: Забей это у автора не то с генами
lulinalex: да?! :-) я СЧАСТЛИВ!! :-) СПАСИБО!!!
XXX: Его в комментах вежливо умыли что лучше огрести ав из за nil чем проезд по памяти из за записи в убитый объект
lulinalex: :-)
lulinalex: о чём gunsmoker и писал...
XXX: Он согласился хотя топик не снес
P.P.P.S. Не знаю уж кто такой "abauer" и чем он так "уважаем", но моё "уважение" к нему - ПОДОРВАНО... Раз (и думаю) - НАВСЕГДА...
Allen Bauer - один из отцов делфи, главный за RTL. Вот как он о себе говорит:
ОтветитьУдалитьI am the Embarcadero Chief Scientist with my main responsibility of overseeing all the developer tools. I have been on or associated with the Delphi/C++Builder teams since before their inception. I've also had the distinct honor of working with Anders Hejlsberg for many of those years
Мнение человека,который стесняется своего имени и фамилии мне как бэ - неинтересно.
Удалить