The first time you see NSNumber your probably say to yourself “What is the point of NSNumber? I already have int, float, double etc”. Although this may be true, there are many occasions when you actually need to use NSNumber.
Adding a number to an array
NSArray (NSMutableArray etc) does not allow you to add primitive types to it. This is because an NSArray is simple a set of pointers to the Objects you add to it. This means if you want to add a number to the array, you first have to wrap it in a NSNumber.
NSArray *numbers = [NSArray arrayWithObject:[NSNumber numberWithInteger:2]];
Number type conversion
NSNumber allows you to easily convert the type of a number e.g. from an int to a float
NSNumber *number = [NSNumber numberWithInteger:2]; float floatValue = [number floatValue];
Perform selector calls
Once you have used Objective-C for a while you may come across
performSelector. This allows you to carry out advanced techniques like performing a selector after a given delay.
[magicObject performSelector:@selector(performMagicWithNumber:) withObject:[NSNumber numberWithInteger:2] afterDelay:1.0];
This the equivilant of doing the following without a delay:
[magicObject performMagicWithNumber: [NSNumber numberWithInteger:2]];
Persisting Objects (CoreData)
Archiving Objects is a lot easier than archiving primitive types, as NSNumber inherits from NSObject you can use various archiving and de-archiving methods on them. CoreData actually requires you to use NSNumber for persistent storage. One thing that may not be obvious at first glance, is that CoreData (and Objective-C) considers BOOL as a NSNumber.
You may write the best selling application on the Appstore and never use NSNumber, but if you need to persist your objects or you need access to the various performSelector calls, NSNumber is obviously the way to go.