gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Class clusters: MacOSX/GNUstep differences?


From: Richard Frith-Macdonald
Subject: Re: Class clusters: MacOSX/GNUstep differences?
Date: Wed, 1 Sep 2004 16:49:04 +0100


On 1 Sep 2004, at 15:53, Ronan Collobert wrote:

Hello,

I have to implement a true subclass of the NSArray class. My code works
well under MacOS X, but does a "seg fault" under GNUstep.

After looking at the code of NSArray.m and GSArray.m, I found that in
GNUstep, if we want to implement a subclass of NSArray we have to derive
not only the standard two primitives count: and objectAtIndex:
but also

- (id) initWithObjects: (id*)objects count: (unsigned)count;

Indeed, in NSArray.m, the init method is implemented as
- (id) init
{
  return [self initWithObjects: (id*)0 count: 0];
}

and initWithObjects: as
- (id) initWithObjects: (id*)objects count: (unsigned)count
{
  [self subclassResponsibility: _cmd];
  return nil;
}

I understand that if we define initWithObjects: in a subclass, then it's
cool because all other init methods of NSArray will work well in the
subclass. However, we are *forced* to declare this method in the
subclasses with GNUstep, which is not (to my opinion) what is specified in
the Cocoa framework. Here is a cut and paste of a discussion on class
clusters by apple:
(see
http://developer.apple.com/documentation/Cocoa/Conceptual/Foundation/ Concepts/ClassClusters.html)

"Your subclass should declare its own init... [...] It should not
rely on any of those that it inherits. To maintain its link in the
initialization chain, it should invoke its superclass's designated
initializer within its own designated initializer method. Within a class cluster, the designated initializer of the abstract superclass is always
init"

Note that in the NextStep3.3 specifications, there is exactly the same
text.
(see
http://www.channelu.com/NeXT/NeXTStep/3.3/nd/Foundation/ IntroFoundation.htmld/index.html)

Interesting, I never saw the EOF documentation.

And I never saw in the Apple/NextStep documentation that initWithObjects:
has to be considered as a primitive method.

Maybe the OpenStep specifications are different, but the document provided
on www.gnustep.org seems not to talk about this particular point.

I'm pretty certain that the OpenStep specification did not say this ... because at some point when working on class clusters I wanted a clear policy on initialisation and couldn't find anything in the spec ... though I do remember finding something saying that a subclass needed to override the superclass initialisers in order to
prevent those initialisers returning instances of other classes.

I therefore adopted the policy that class clusters should, like any other class, have designated initialisers. Also that, like other classes, the designated initialiser should be the 'richest' initialiser. So that, in GNUstep it should be possible to override a single designated initialiser and have all the other
initialisers work as expected, ie to improve on the OpenStep spec
That's why the GNUstep class documentation specifies the designated initialiser
of NSArray to be initWithObjects:count:

Anyways, it is quite annoying, because I cannot have the full
compatibility between MacOS X and GNUstep. Even if I declare this
initWithObjects: method in my code, in MacOS X I should have a line
such as
[super init]
according to what apple says, which will cause an infinite loop under
GNUstep.

Maybe this has been already discussed in the past, but I didn't find
anything in the mailing list archives. Any comments on this?

I know class cluster iniitialisation was discussed in the past ... but it
was years ago and may have been in a private mailing list back then.

I think the GNUstep behavior is superior in that it makes initialisers
reliably available so that creators of subclasses don't need to override
them all, and it makes the behavior of class clusters consistent with
that of other classes ... but I sympathise with the portability problem.

I'm reluctant to make things harder for GNUstep coders by forcing
them to implement initialisers that the abstract class ought to handle,
but I can't immediately see an elegant portability solution.

The obvious inelegant one is -

- (id) initWithObjects: (id*)o count: (unsigned)c
{
#ifdef MACOSX
  if ((self = [super init]) == nil)
    {
      return nil;
    }
#endif
  // Your initialisation here
  return self;
}





reply via email to

[Prev in Thread] Current Thread [Next in Thread]