I have a window that is opened to perform a task. The task is run from a timer, and when complete it raises an event, then hides itself (does not close, just hide). App has attached a handler to the event, and it gets information from the window via a method.
The problem is, the event handler is run “some of the time”. So I am not sure whether I’m setting up the handler wrong, there is a bug in xojo, or perhaps something i am doing is corrupting memory.
One thought I have, is whether closing the window would require that the handler be attached again? That is, if there is a window in my application, and without opening it, I attached a handler to it’s event, can I expect this to work when the window is opened?
The problem with “calling up” like that, is that it creates coupling between the two parts of the program. App and window now need each other, to compile. Using an event, window does not need to know about app. App still knows about window…window is it’s “junior executive” you might say.
Coupling like that eventually forms a mass where no part of the program can be separated from the other parts. So it works against reusable code. For instance, my window performs discovery (finds out what hardware is attached). I might want to write 3 different programs that all use that functionality.
I have never used removeHandler. I don’t know why that would be needed, if the handler was in use for the lifetime of the program.
I guess you are right…because the App now has the AddHandler instruction which couples it to the window. But I am treating the App object as the integrator. It is the part of the program that integrates the other parts. It knows about all the parts already, that is its job.
The approach to design that I find is most workable is hierarchical. By following the rule of never calling up the hierarchy, I find that makes my programs very easy to understand. No spaghetti results.
I suppose one could follow an opposite rule and it would work just as well. Just following a rule simplifies the code.
Another approach to reducing coupling is the use of interfaces, which I think is pretty much Standard Operating Procedure for OOP. I think that is a good idea, though a partial solution and adds some complexity in that it adds another piece. I could for instance have the window call into an interface which the app implements. But I still need to carry around that interface with the window. The interface is lightweight, it has no real liabilities that come with it (ie other connections to objects that turn the code into one mass).
For now, I am not unhappy with the event approach. I just want to know why it doesn’t work reliably! If no one can answer that question, then I may need to follow your advice.
I’m not saying the integrating component = decoupling. I am saying that is a design decision, already made and acceptable to me, so I am not worried about coupling with that component.
I think I will try your code. That is, actually remove the handler, and close the window, and reconstruct the whole thing each time. It seems like more work than should be necessary, but if that’s what it takes to make it work, so be it.
Addhandler when used with AddressOf creates a reference to the object that owns the handler method (App in your case) that is held by the object whose event is being handled (the window). Since objects in Xojo are refcounted, you must use RemoveHandler to properly decrement the refcount for the handler object (App). Your specific case is a little special since the App instance exists for the duration of the program anyway.
Additionally, if the object whose event is being handled (window) is a property of the handler object (App) then using AddressOf creates a circular reference that prevents the refcount on both objects from reaching zero until the handler is removed. This can be intentional, but more often than not this is a bug.
In such cases it may be preferable to use WEAKAddressOf to assign event handlers. WeakAddressOf does the same thing as AddressOf but without creating a reference (c.f. WeakRef class.) Event handlers assigned using WeakAddressOf do not need to be explicitly removed.
Deciding when and how to use AddressOf vs WeakAddressOf is based on how you want the objects to be destroyed.
I have a similar issue: I have a handler that sends a message to a web viewer, that is either invoked by a method triggered by a timer or a method triggered by a message received by a socket; both methods are members of the same class.
The timer-triggered methods behaves well; data is formatted and sent. The socket-triggered method sends, as a test, the same message (which should trigger the event handler) but is ignored.
Any pointers as to how to go about debugging this?
As an additional datapoint, I called the successful timer-based method from within the unsuccessful socket-based one, and the event no longer triggered its handler - thus it appears it had been disabled. How can this happen?