2012-01-31

alloc-init pattern's rationale

1.23: sci,bk.adda/lang"obj'c/alloc-init pattern's rationale:
. in {Buck, Yacktman}`Cocoa Design Patterns
they explain the rational for separating init from alloc;
eg, x`= NSString`alloc`init .
. alloc can be a class function because
the mem requirements are known from
the interface ivars list defined by
self and self's superclasses .
. alloc works something like malloc,
only it is accepting a list of types
and converting them into the bytes count
that the malloc needs .

. my first reaction to this convention was:
how would you know what to allocate
until you see what there is to init?
these functions should indeed be separate;
but, the init should be calling the alloc,
rather than init being handed alloc's result by parameter .

. one continuing important reason for this convention
is communicating to client who it is that should be
doing the retains:
. the convention is that convenience methods are
using your autorelease pool .
. using the alloc init is your sign that
you own it (you need to auto/release it yourself )

. other than that, I've seen no intrinsic need for it;
... but, how does inheritance complicate things?

. it looks like the main reason is legacy code:
the Cocoa library can't maintain backward compatibility
unless you follow this convention .

. the main reason alloc was a class method,
was that init should be an instance method
but alloc (the source of the instance)
would have to be from a class method
because instance methods work on instances,
so the alloc couldn't be an instance method .
. I'm not sure whether {Buck, Yacktman} said that;
however, some oop evangelist did say that,
and I'd like to show next,
why I don't think it's true .

[1.31: 1.23:
. the usual oop idioms very much depend on
the root object being a pointer to heap node;
-- where that pointer that is the same size
across all objects --
and that pointer exists even before alloc is called .
 . what the object really needs in order to have
 access to some instance var's,
 is to belong to some specific class;
 and,  it could get this either by
 sending an init msg to the specific class it wants
 or by letting the init's param decide on a class,
 based upon the type of initial value assigned
 (for example, when the compiler gets a value literal,
 it can infer a type class from that:
 "(abc) is a string
 123 is a number
 (1,2,3) is an array of number
 (1, "(abc)) is a record in (number, string).
 ) . init figures out what it needs,
 and then calls an alloc to help with that .
 . if the client has a preference for some alloc technique
 that could be a param  of the init,
 initWith (source, allocWith: style ) .]