gioma 19 Posted July 11, 2022 I created two visual components, one referencing the other in the published properties. Example: TComponentA = class(TComponent, IComponentAl) [weak] _ComponentB: TComponentB; //...other code private procedure SetCopmponentB ( const Value: TComponentB); //.. other code published property ComponentB: TComponentB read _ComponentB write SetCopmponentB; //.. other code procedure TComponentA.SetCopmponentB(const Value: TComponentB); begin try _ComponentB := Value; //.. other code except on e:exception do WriteLog('[TComponentA.SetCopmponentB] EX: ' + e.Message); end; end; in the design phase, I add the two components ComponentA: TComponentA and ComponentB: TComponentB in the form. By Deisngh i set the property ComponentA.ComponentB: = ComponentB. Then if I delete ComponentA from design I have no problems, if instead I delete componentB (which is associated with the property of componentA) then Delphi goes into an exception unended loop. What should I add to the code to prevent this from happening? Share this post Link to post
Anders Melander 1815 Posted July 11, 2022 Don't insert tabs in your source. Don't use [weak] Use the notification mechanism built into TComponent: type TComponentA = class(TComponent, IComponentAl) private FComponentB: TComponentB; private procedure SetComponentB(const Value: TComponentB); protected procedure Notification(AComponent: TComponent; Operation: TOperation); override; published property ComponentB: TComponentB read FComponentB write SetComponentB; end; procedure TComponentA.SetComponentB(const Value: TComponentB); begin if (FComponentB <> nil) then FComponentB.RemoveFreeNotification(Self); FComponentB := Value; if (FComponentB <> nil) then FComponentB.AddFreeNotification(Self); end; procedure TComponentA.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if (AComponent = FComponentB) and (Operation = opRemove) then FComponentB := nil; end; 5 Share this post Link to post
gioma 19 Posted July 12, 2022 Thanks a lot, now I try. But it's amazing that Delphi becomes impossible to close for this reason. The error message loop is endless! Share this post Link to post
Anders Melander 1815 Posted July 12, 2022 So evidently there's another problem with your code. You can start by showing us the call stack (click the Details button). Share this post Link to post
Remy Lebeau 1436 Posted July 12, 2022 9 hours ago, gioma said: Thanks a lot, now I try. But it's amazing that Delphi becomes impossible to close for this reason. The error message loop is endless! Did you make sure the rest of TComponentA's code is checking FComponentB for nil before accessing its members? It is hard to diagnose your problem without a complete example. Share this post Link to post
gioma 19 Posted July 15, 2022 On 7/11/2022 at 3:41 PM, Anders Melander said: Don't insert tabs in your source. Don't use [weak] Use the notification mechanism built into TComponent: type TComponentA = class(TComponent, IComponentAl) private FComponentB: TComponentB; private procedure SetComponentB(const Value: TComponentB); protected procedure Notification(AComponent: TComponent; Operation: TOperation); override; published property ComponentB: TComponentB read FComponentB write SetComponentB; end; procedure TComponentA.SetComponentB(const Value: TComponentB); begin if (FComponentB <> nil) then FComponentB.RemoveFreeNotification(Self); FComponentB := Value; if (FComponentB <> nil) then FComponentB.AddFreeNotification(Self); end; procedure TComponentA.Notification(AComponent: TComponent; Operation: TOperation); begin inherited; if (AComponent = FComponentB) and (Operation = opRemove) then FComponentB := nil; end; I need the weak parameter, because in real use they are two components that refer to each other. I solved it using the notification mechanism . Thank you! Share this post Link to post
Anders Melander 1815 Posted July 15, 2022 36 minutes ago, gioma said: I need the weak parameter, because in real use they are two components that refer to each other. No you don't. I understand why you used it but there are always better ways to solve a problem than using [weak]. Contrary to what the documentation states [weak] isn't named named after the type of reference. It's named after the design skills of people who choose to use it to manage references. 🙂 1 3 Share this post Link to post
Dalija Prasnikar 1404 Posted July 15, 2022 48 minutes ago, gioma said: I need the weak parameter, because in real use they are two components that refer to each other. Weak attribute only works on interface references, not on object references. In your case, with TComponent reference, compiler just ignores weak attribute. 1 Share this post Link to post
Dalija Prasnikar 1404 Posted July 15, 2022 3 minutes ago, Anders Melander said: No you don't. I understand why you used it but there are always better ways to solve a problem than using [weak]. Contrary to what the documentation states [weak] isn't named named after the type of reference. It's named after the design skills of people who choose to use it to manage references. 🙂 Weak references are integral part of ARC as memory management system. Because ARC was not main memory management system in classic compiler and was just an "add on", most code didn't require them or could use pointers that are equivalent of unsafe attribute. Support for weak references in classic compiler was added only after they were added on mobile ARC compiler which requires weak references in order to have functional memory management system. Proper coding pattern for ARC memory management would indeed require using weak attribute in the similar circumstances (code) OP had. In other words, if we would rewrite RTL and VCL to follow ARC rules then the OP original code would be the correct one, and we would not need nor have TComponent notification system. 1 Share this post Link to post
gioma 19 Posted July 15, 2022 19 minutes ago, Anders Melander said: No you don't. I understand why you used it but there are always better ways to solve a problem than using [weak]. Contrary to what the documentation states [weak] isn't named named after the type of reference. It's named after the design skills of people who choose to use it to manage references. 🙂 16 minutes ago, Dalija Prasnikar said: Weak attribute only works on interface references, not on object references. In your case, with TComponent reference, compiler just ignores weak attribute. Right, you are right! I have used weak on other occasions with Interfaces, in this case it is a TObject so it makes no sense to use it. Distraction error Thanks again! Share this post Link to post
gioma 19 Posted July 15, 2022 The shocking thing though is that if you make a mistake in creating a component and then install it, Delphi goes into an unending error loop and you are forced to close it from the task manager! The IDE is still not very stable, although it costs a lot and its competitors are free! I have been using Delphi for 16 years (Delphi 5, 7, delphi 2005 .. up to Delphi 11 Alexandria), in the beginning it was much better than Visual Studio .. now it is far behind and the updates are very, very, very slow to come out .. Visual studio has updates every week! And I repeat .. Visual Studio is free! Share this post Link to post
gioma 19 Posted July 15, 2022 sorry for the outburst, but sometimes it's really frustrating to work with Delphi .. you waste a lot of time with nonsense! Share this post Link to post
Anders Melander 1815 Posted July 15, 2022 2 hours ago, gioma said: The shocking thing though is that if you make a mistake in creating a component and then install it, Delphi goes into an unending error loop and you are forced to close it from the task manager! Not very shocking if you understood what was going on. When you install a component your code will be run as a part of the IDE process. If your component code goes into an endless loop then you will have hung the IDE. Nothing surprising there. 2 hours ago, gioma said: And I repeat .. Visual Studio is free! So is Delphi. I'm assuming you're a hobbyist because otherwise VS isn't free AFAIK. Share this post Link to post
Brian Evans 109 Posted July 15, 2022 I think you would benefit from taking a break and acquiring some Delphi custom component development and debugging skills. Impatience to do something when you have not yet acquired the necessary skills and knowledge usually leads to frustration. The basics of component development and debugging have not changed much so even older books/guides are still useful. Ray Konopka wrote some early books on Delphi component development any which would be a good resource if you can get your hands on one. 1 Share this post Link to post
gioma 19 Posted July 18, 2022 (edited) On 7/15/2022 at 3:16 PM, Anders Melander said: Not very shocking if you understood what was going on. When you install a component your code will be run as a part of the IDE process. If your component code goes into an endless loop then you will have hung the IDE. Nothing surprising there. So is Delphi. I'm assuming you're a hobbyist because otherwise VS isn't free AFAIK. I was a hobbyist when I was 12 and I was programming in Basic with the Vic20.. Visual studio professional has a lower price base. Yes, I understand that the error was caused by me, the IDE must rightly report it to me, but then it cannot go into an infinite loop of errors. On 7/15/2022 at 3:29 PM, Brian Evans said: I think you would benefit from taking a break and acquiring some Delphi custom component development and debugging skills. Impatience to do something when you have not yet acquired the necessary skills and knowledge usually leads to frustration. The basics of component development and debugging have not changed much so even older books/guides are still useful. Ray Konopka wrote some early books on Delphi component development any which would be a good resource if you can get your hands on one. I have been developing with Delphi for many years (more than 16), but there are many aspects of programming and you never stop learning. I don't often have to create a component, I usually buy them, use them and modify them if necessary. In this case I had to make a component from 0, so I was faced with new problems for the first time. I am not frustrated, but I expect that if I make a mistake I can analyze it, understand it and fix it. If the IDE goes into an endless loop of errors I can't do anything anymore. Sometimes for example it happens that when I update the component, if I go to recompile delphi it blocks the BPL file. The only way I have to re-install it is to close and reopen Delphi. These are time wasters that you would not want to encounter when you have to develop in precise timing. Edited July 18, 2022 by gioma Share this post Link to post
PeterBelow 239 Posted July 18, 2022 When you deverlop a custom component it is a good idea to use a test project first in which you create an instance of the component in code. This allows you to debug the run-time behaviour of the component without endangering the IDE itself. Only when everything works as it should do you add it to a design-time package and install it, to validate the design-time behaviour. If you need to add a custom property or class editor these can also be developed and tested in the test project, by just doing what the IDE designer does for invoking them. I don't remember the details since it has been literally decades since I last needed to do this, but it can be done. 1 Share this post Link to post
gioma 19 Posted July 18, 2022 5 hours ago, PeterBelow said: When you deverlop a custom component it is a good idea to use a test project first in which you create an instance of the component in code. This allows you to debug the run-time behaviour of the component without endangering the IDE itself. Only when everything works as it should do you add it to a design-time package and install it, to validate the design-time behaviour. If you need to add a custom property or class editor these can also be developed and tested in the test project, by just doing what the IDE designer does for invoking them. I don't remember the details since it has been literally decades since I last needed to do this, but it can be done. It's a great idea, I did a similar thing, but the IDE got stuck anyway. Share this post Link to post