How to prevent NilObjectExceptions on Quit?

Did my suggestion not do the trick?

I have no way of evaluating the effectiveness of any of the proffered suggestions because I can’t get it to throw the exception again. Got pulled away on some other stuff but will bang on it harder asap, and as soon as I can get some semblance of repeatability I’ll start trying fixes. I’m sure yours will work :slight_smile:

1 Like

With greetings from the N:

IF I understand correctly the timer is a property of the control ?
If so kill the timer when the controls close method or event is called so the timer stops when the control & its property are destroyed

Or is the timer a property of the Window the control is on ?
If so use the Windows close method/event
If this is a window subclass you can override the Close method and implement the close /cancel close events and pass them along with raise event as well

The underlying issue is that a timer with a weak address target for he action event handler doesnt check if the target is nil before trying to call it

Xojo should just fix that so it does then this problem goes away in general

I have a mac desktop application, that has an exception on quit, and no timer inside.
cannot figure where is the problem.
I have a button with a “quit” on it as the only method
if I do file->quit it quits ok
if I clic on the button the app quits with a system error.

A pushbutron or a bevelbutton?

If all else fails you can still be rude:

declare function NSClassFromString lib "Cocoa" ( aClassName as CFStringRef ) as integer
declare function sharedApplication lib "Cocoa" selector "sharedApplication" ( classRef as integer ) as integer
declare sub terminate lib "Cocoa" selector "terminate:" ( appRef as integer, sender as integer )

Dim appInstance as integer = sharedApplication( NSClassFromString( "NSApplication" ) )
terminate( appInstance, appInstance )

In some circumstances I have to quit my app that way.

a pushbutton

Yes.

Yes, I’m sure this and any of the other approaches suggested will probably work.

I’m not sure how realistic it is to expect that Xojo could do nil checks at runtime, but I do think that we can reasonably expect Xojo to be able to close an application with a sequence that prevents errors like this from occurring, without requiring users to implement workarounds. IMO there’s nothing wrong with my code, and I shouldn’t be the one who has to worry about zombie objects calling code that’s been destroyed by the framework during an application quit - the framework should handle that.

Respectfully, if you have not balanced AddHandler with RemoveHandler, your code is faulty and Quit is just a manifestation of the existing problem.

The RemoveHandler page says this specifically and I’m going to get that note into the AddHandler page too. It’s only in the example right now.

Fair enough, although the documentation is pretty stingy with details, saying only that you should remove a handler when you’re “finished with it”, which I interpreted as meaning “If you’re finished with it while your program is still running”, not as “before the application tries to quit”. If all handlers need to be removed prior to application quit, then the docs should say so explicitly.

I still think the framework could/should do this: if the the app is quitting, automatically remove all handlers, and destroy timers, sockets, and SerialConnections before anything else.

I’ve updated the online docs to make this more clear.

3 Likes

Now that’s what I call responsive customer support!

(Reminder that I don’t work for Xojo, though, just helping out.)

Yeah, but you have write access to the documentation, and that’s a Big Thing.

2 Likes

But why would it be necessary to do more than turn the timer off? Then the timer becomes just another quiescent object that gets destroyed when the app quits.

On quit, you’re right. But the intermediate event here is the window closing, and you don’t want to leave unneeded handlers laying around after that happens. If nothing else, you’ve likely created a memory leak, even if it’s (probably) tiny.

OK, thanks - that’s helpful.

I can only guess this is about the use of the mouse or activation of the window. Have you tried putting a timer (off by default, 1 second as the period), moving the code from the button to the timer and starting the timer in the button? (just to see whether it’s a UI problem or a “quit” command issue)

Wouldn’t that prevent one foreseeing how the code will work/fail, especially if the destruction order isn’t predictable or expected?

Agreed, much better for encapsulation and portability to do this in the object’s Destructor rather than in window.close, assuming it will be effective there.

1 Like