Understanding Objective-C Number Objects

Revision as of 15:48, 20 November 2009 by Neil (Talk | contribs)

Revision as of 15:48, 20 November 2009 by Neil (Talk | contribs)

In Objective-C 2.0 Data Types we looked at the basic data types supported by Objective-C including a range of types for working with numbers. These data types are what are known as primitive types in that they simply allow values to be stored in memory and are not objects.

In order to work with numbers in object form, Objective-C provides the NSNumber class. This class is one of the stranger additions to the Objective-C language in that functionally speaking, number objects don't give you anything that you can't already do with primitive number types. It seems the sole purpose of the NSNumber class is to allow numbers to be stored in an NSArray object, which only handles objects.

In this chapter we will take a look at the NSNumber class and provide an overview of how to work with number objects.

Creating and Initializing NSNumber Objects

As previously discussed, the primary purpose of the NSNumber class is to allow the storage of primitive numerical data in the form of an object. The NSNumber class is able to store signed and unsigned char, short, integer, int, long and long long data types and also float, double and Bool values.

The NSNumber class contains a set of class methods designed specifically for creating objects and initializing them with values of a particular numerical data type. The naming convention for these class methods is as follows:

numberWith<Unsigned><Type>

The full list of creation and initialization methods is as follows:

numberWithBool
numberWithChar
numberWithDouble
numberWithFloat
numberWithInt
numberWithInteger
numberWithLong
numberWithLongLong
numberWithShort
numberWithUnsignedChar
numberWithUnsignedInt
numberWithUnsignedInteger
numberWithUnsignedLong
numberWithUnsignedLongLong
numberWithUnsignedShort

Because these are class methods, rather than instance methods, they are called on the class rather than on an existing object. For example, to create an NSNumber object called myFloat, configured to hold a float value, we could write the following code:

NSNumber *myFloat;

myFloat = [NSNumber numberWithFloat: 10.09];

Once executed, the above code will create a new NSNumber object and assign the floating point value of 10.09 to it.

Getting the Value of a Number Object

The current value stored in a number object can be obtained using one of a number of retrieval instance methods. The type of value retrieved depends on the method used. The full list of retrieval instance methods is as follows:

boolValue
charValue
decimalValue
doubleValue
floatValue
intValue
integerValue
longLongValue
longValue
shortValue
unsignedCharValue
unsignedIntegerValue
unsignedIntValue
unsignedLongLongValue
unsignedLongValue
unsignedShortValue

For example, we can extend our example to retrieve and display the value stored in our number object as follows:

NSNumber *myFloat;
float floatvalue;

myFloat = [NSNumber numberWithDouble: 10.09];

floatvalue = [myFloat floatValue];

NSLog (@"Value = %f", floatvalue);

Note that the method used to retrieve the value stored in a number object must match the method used to store the object. An attempt, for example, to retrieve a char from an object initialized as double will provide an unexpected result.


Comparing Number Objects

To compare the values stored in two number objects it is necessary to use either the isEqualToNumber or compare methods. These are both instance variables, and as such are called on one object instance, passing through the second object as an argument.

isEqualToNumber returns a Boolean value depending on whether the two objects contain the same numbers. For example:

NSNumber *myFloat1;
NSNumber *myFloat2;

myFloat1 = [NSNumber numberWithDouble: 10.09];
myFloat2 = [NSNumber numberWithDouble: 10.08];

if ([myFloat1 isEqualToNumber: myFloat2])
        NSLog (@"Numbers are equal");
else
        NSLog (@"Numbers are not equal");

The compare method is used when you need to know whether one number is less than, greater than or equal to another when those numbers are held in number objects. The method returns the result of the comparison in the form of an NSComparisonResult enumeration. Possible settings are NSOrderedSame if the numbers are equal, NSOrderedAscending is the value stored in the first object is less than the number stored in the second and NSOrderedDescending if the opposite is true:

myFloat1 = [NSNumber numberWithDouble: 10.09]; 
myFloat2 = [NSNumber numberWithDouble: 10.08]; 
NSComparisonResult result; 
    
result = [myFloat1 compare: myFloat2];

if (result == NSOrderedSame)
        NSLog(@"Numbers are equal");
else if (result == NSOrderedAscending)
        NSLog(@"Float1 is less than Float2");
else if (result == NSOrderedDescending)
        NSLog(@"Float1 is greater than Float2");

Getting the Number Object Value as a String

In order to convert the value stored in a number object to a string, the stringValue instance method is provided by the NSNumber class. This method returns the current value as a string object (for more information on string objects refer to Working with String Objects in Objective-C):

NSNumber *myFloat;

NSString *myString;
      
myFloat = [NSNumber numberWithDouble: 10.09];

myString = [myFloat stringValue];

NSLog (@"Number as string is %@", myString);