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 21:59:41 -0700

*** I hope this is not a dupe. I sent one before I confirmed my
subscription, and it never showed up...

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]