Official Guidance on Constructors ? (Nougat)

Continuing the discussion from Contstructors and Init* Methods - No information on the wiki:

Is the information in the reply to this still correct ?

I have found myself adopting the Obj-C-like, explicit alloc.init pattern:

obj := MyClass.alloc.initWithFoo( foo );

I tried following the guidance in the above reference post, but code completion failed to offer a “withFoo” ‘constructor’ and if I ignored this and tried to compile with it anyway, it failed.

obj := new MyClass.withFoo( foo );  // Computer says "no"

I started getting creative and thought that perhaps “new ClassName” had been reduced to a more direct correspondence with ClassName.alloc, so tried restoring the initialiser method to its full name, but the compiler again rejected this because my initialiser method is not static (and rightly so):

obj := new MyClass.initWithFoo( foo );  // Computer says "no"

So thinking that perhaps the alloc equivalent was now “new ClassName()” my next attempt was to nudge the compiler into more certainly creating an instance before invoking the initialiser:

obj := new MyClass().initWithFoo( foo );

This compiles and indeed runs, but the initialiser doesn’t appear to function correctly.

In the concrete case the class is a custom view and the initialiser parameter is a CGRect that determines the frame of a new view instance. Using my long-hand alloc.init approach, this works perfectly. Using the above incantation the view is not initialised with the correct frame (though I have not investigated further to determine what frame it is getting).

obj := MyClass.alloc.initWithFoo( foo );         // works perfectly
obj := new MyClass().initWithFoo( foo );         // not right at all ?

Could I get a definitive answer on the right way to define and invoke constructors on classes in Nougat ?

I am perfectly happy to adopt the alloc.init pattern, but would appreciate knowing whether this is the officially supported mechanism or I am missing out on some syntactic sugar that I could otherwise take advantage of.

If you’re using init, these are regular methods, and defined and called as such.

var obj := MyClass.alloc().initWithFoo() bar(...);

you’ll only want to call them on a freshly alloc’ed object, because otherwise you might be initializing stuff twice, which can cause unexpected side effects, depending on how it’s implemented.

This of alloc() as a static/class method that return an allocated but uninitialized instance. and of into() as an instance method you call on that, that returns the class itself again (or a new/different instance potentially — which you should always make tore to keep/use the result of init(), and not store the result of alloc() and then just call init() on it).

If you are using constructor/new syntax, the “init” part of the names dropped,and the remiande rid used w/o dot, as second (and possibly third, forth, etc) part to the new call:

var obj := new MyClass withFoo(...) bar(...)

Ah, it was the dot-less aspect of the new syntax that I had missed:

object := new MyClass.withFoo( foo );  // wrong
object := new MyClass withFoo( foo );  // right ?

Thanks for clearing that up. :slight_smile:

correct.