When does a constructor finish constructing?

In one of my apps I need to log certain classes as they are constructed. I do this in a dictionary with a reference UUID pointing to each constructed class.

The classes are arranged with one master class, and a number of sub-classes and sub-sub-classes. I use introspection to build the properties of the classes from a JSONItem. Some of the properties are also classes or class arrays of the same master class so I check the dictionary for the UUID prior to launching a new constructor. I have noticed that sometimes the class shows itself as a nil value (as if the construction has not yet been completed) if I do the property construction within the constructor method.

The question is when is it safe to assume that the class has been constructed and can be added to the dictionary? Is it when the subclass.constructor is called, or when the masterclass.constructor is called (via super.constructor) or when the superclass.construcor has terminated or when the subclass.constructor has terminated?

The constructor is done when it returns.

Thanks Greg.

We often use the constructor to populate properties, often including references back to the calling class from other classes in a hierarchy. e.g. A.constructor calls B.constructor(self) which uses the self reference to populate a property referring back to A.

Trying to codify what is good practice in a constructor:

Is it safe to assume that if I write self to a property during the constructor, then the property will be populated with the correct reference? Example here might be adding a reference to the class within a dictionary.

Is it correct to assume that if I try to read from that property or reference in a dictionary to the class then the result may not yet be the completed class - so may return nil. Example here might be trying to read back the class from the dictionary.

i.e. it is safe to write to properties(etc) referring to the calling constructor, but not to read back properties(etc) referring to the calling constructor.

Following up on this older discussion. What is the best way to trigger the initialisation of properties within a class after the constructor has completed, and to avoid the potential constructor looping highlighted above. Obviously I can use a timer to trigger action immediately after the constructor completes, but this feels heavy - adding a timer to every class created - is there a more economic way?

The Open event?

For a control or window yes, but classes don’t have events, unless I build them myself.

Yes, but you do not have the aforementioned issue, because there are no properties settable in the IDE for these kind of class instances.

Eli - perhaps I’ve not made the issue clear enough.

It is specific to classes, where on construction I’d like to populate a range of its properties with either default values or values extracted from a database.

Some of these properties are also classes, which themselves may refer back to the class that has called them (Not an infinite loop but just a reference to parent class).

If I populate the properties inside the Constructor - then it is possible that they won’t be referenced properly - per the comment from Greg above. So it is necessary to populate them after the constructor has finished. That sounds like good practice anyway.

So the question is, what is the best method to use to trigger an action after the class constructor has finished. At present I’m using a timer with period of 0 so that it runs as near to possible after the constructor has finished. I was questioning whether there was a better way.

Greg didn’t say anything like this. He said:

By the way, constructors in Xojo are regular methods. They are called immediately after class instances are allocated in memory, that is the only special thing about them.

Then there is a difference between what Greg has said and what you are saying.

My reading is that Greg is saying the construction of the class is done when the constructor returns.

Whereas you are saying the construction is done and then the constructor method is called.

There are two stages of “constructing” an instance of a class

both are done as part of the NEW operator

  1. allocate memory
  2. run initialization code

step 1 is done in the framework and you have no control over that - nor any influence

step 2 is the “constructor” - this is your code
This really is an initializer (it initializes the allocated object to a default state) and can actually be called at any time
step 2 is automatically called by the framework allocation code IF it exists

constructors “know” nothing about hierarchies of references or properties etc so YOU have to write your code to construct things in whatever you decide is “the right order” so your objects are fully constructed as you expect

Norman - thanks for the clarity - it was Greg’s statement then that had me confused and looking for the answer to the wrong question.

I do have instances where I was pretty sure the property had been correctly populated in the constructor, but when subsequently (but within the original construction method) referenced by another constructor it was empty. So I was tracking down the wrong problem.

[quote=356988:@James Pitchford]Then there is a difference between what Greg has said and what you are saying.

My reading is that Greg is saying the construction of the class is done when the constructor returns.

Whereas you are saying the construction is done and then the constructor method is called.[/quote]
I did not say anything the like.

Eli - when I said the “construction is done” I meant, using your words, that the “class instances are allocated in memory”. This is consistent with Norman’s description.

Whereas Greg’s statement implied to me that the “class instances are allocated in memory” only after the “constructor returns”.

That would be impossible.

I did not read that in Greg’s comment. In addition, @Norman Palardy was quite clear that memory allocation comes first and code execution second.

[quote]There are two stages of “constructing” an instance of a class

both are done as part of the NEW operator

allocate memory
run initialization code
step 1 is done in the framework and you have no control over that - nor any influence

step 2 is the “constructor” - this is your code
This really is an initializer (it initializes the allocated object to a default state) and can actually be called at any time
step 2 is automatically called by the framework allocation code IF it exists[/quote]

Yes, I saw that Louis - thank you. I guess Greg’s statement must have different interpretations.

if you add a constructor to a class its “done” when that method exits

thats the very end of step #2 I listed above