gnustep-dev
[Top][All Lists]
Advanced

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

Q) NSNumber class factory methods, such as numberWithXXX


From: Jaeyang Park
Subject: Q) NSNumber class factory methods, such as numberWithXXX
Date: Wed, 15 Mar 2006 17:25:17 -0700

In NSNumber.m, there are a few class factory methods. (I hope I'm
right with the term).
For example, numberWithFloat as shown below.

+ (NSNumber*) numberWithFloat: (float)value
{
  NSNumber  *theObj = nil;

  // if class is NSNumber, replace by appropriate object
  if (self == abstractClass)
    {
      theObj = (NSNumber*)NSAllocateObject(floatNumberClass, 0,
                                           NSDefaultMallocZone());
      theObj = [theObj initWithBytes: &value objCType: NULL];
    }
  else // alloc class and init with object intWithXX method
    {
      theObj = [[self allocWithZone: NSDefaultMallocZone()]
                 initWithFloat: value];
    }

  return AUTORELEASE(theObj);
}


I assume the if-statement, "if (self == abstractClass)" checks whether
the message is sent to NSNumber or any of concrete sub classes of
NSNumber.
As in
    [NSNumber numberWithFloat:13.0]      ---- A)

or [NSFloatNumber numberWithFloat:13.0]  ---- B)

So, if A is the case,
this part will be excuted,
{
  theObj = (NSNumber*)NSAllocateObject(floatNumberClass, 0,
                                       NSDefaultMallocZone());
  theObj = [theObj initWithBytes: &value objCType: NULL];
}

Or, if B (or similarly with other concrete sub calsses) is the case,
the following will be excuted.
{
  theObj = [[self allocWithZone: NSDefaultMallocZone()]
             initWithFloat: value];
}

I hope I'm on the right track so far.

Now, the question is that what is the difference(s) between two body
of statements.
If I follow the second (else-part) part,
I get an instance from one of concrete sub class, in this case of B,
NSFloatNumber using Zone. Then, the message initWithFloat: is sent to
that instance. Since, NSFloatNumber does not override initWithFloat:
method, the one in NSNumber will be used.
Here's the implementation,

- (id) initWithFloat: (float)value
{
  RELEASE(self);
  self = (NSNumber*)NSAllocateObject(floatNumberClass, 0,
    NSDefaultMallocZone());
  self = [self initWithBytes: &value objCType: NULL];
  return self;
}

The first line  RELEASE(self) releases self, thus renders [self
allocWithZone: NSDefaultMallocZone()] from 'else-part' as long as we
have an instance. The instance is created only to call an instance
method in this case, initWithFloat:
Now, we got new instance with the second statement, and initialize it
in the next line; then that object is returned.

So the 'else-part' can be written as this,
    theObj = (NSNumber*)NSAllocateObject(floatNumberClass, 0,
        NSDefaultMallocZone());
    theObj = [theObj initWithBytes: &value objCType: NULL];

And these two lines are identical to 'then-part' of the if statement.
If I'm not mistaken, I don't see the reason for the if-statement at
all. Eventually the code executed is the same in either case. Just
'else-part' is slower.

Am I missing something? (The odds are pretty high in this case, since
I'm a virtually novice in Objective-C and GNUstep/Cocoa/OpenStep)




reply via email to

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