2014年10月30日 星期四

int vs. NSInteger vs. NSNumber

NSInteger vs. int

NSInteger is typedef'ed based on the target architecture. In other word, it's an architecture-safe (64 vs 32 bit) type to support different platforms and implementations of C. Targeting a 32-bit CPU and OS it's 32-bits wide, on a 64-bit OS it's 64-bits wide.

What follows is how NSInteger is defined in NSObjCRuntime.h file :

And this is what Apple say in Foundation Data Types Reference :
When building 32-bit applications, NSInteger is a 32-bit integer. A 64-bit application treats NSInteger as a 64-bit integer.

Simply, the NSInteger typedef does a step for you: if the architecture is 32-bit, it uses int, if it is 64-bit, it uses long. Using NSInteger, you don't need to worry about the architecture that the program is running on. 

Apple recommends that you use NSInteger over normal types anyway, I would assume for portability!

結論:除非你有特定要int或是long,要不然就建議用NSInteger,這樣就不必去煩惱使用者用的是32-bit還是64-bit的iDevice。

更深入探討

Why use int at all?
Apple uses int because for a loop control variable (which is only used to control the loop iterations) int datatype is fine, both in datatype size and in the values it can hold for your loop. No need for platform dependent datatype here. For a loop control variable even a 16-bit int will do most of the time.
Apple uses NSInteger for a function return value or for a function argument because in this case datatype [size] matters, because what you are doing with a function is communicating/passing data with other programs or with other pieces of code; see the answer to When should I be using NSInteger vs int?in your question itself...
Apple use NSInteger (or NSUInteger) when passing a value as an argument to a function or returning a value from a function.
資料來源:http://stackoverflow.com/a/5320359/3295047

延伸閱讀:64-Bit Transition Guide for Cocoa Touch



NSNumber

NSNumber is an Objective-C class, a subclass of NSValue to be specific. Where a NSInteger or int will fit in a register, a NSNumber is an object that can hold/encapsulate any scalar type (IIRC - I don't use NSNumber if I can help it.  Way too slow.), It can be used when you need an NSObject that holds a scalar value.

You can create an NSNumber object from a signed or unsigned char, short int, int, long int, long long int, float, double or BOOL.

One of the primary distinctions is that you can use NSNumber in collections, such as NSArray or NSSet, where an object is required. For example, if you need to add a float into an NSArray, you would first need to create an NSNumber object from the float:
1
2
3
4
float percentage = 40.5;
...
// Create NSNumber object, which can now be inserted into an NSArray
NSNumber *percentageObject = [NSNumber numberWithFloat:percentage];

Cocoa提供了NSNumber類來包裝(即以物件object形式實現)基本數據類型。

例如以下創建方法:
+ (NSNumber*)numberWithChar: (char)value;
+ (NSNumber*)numberWithInt: (int)value;
+ (NSNumber*)numberWithFloat: (float)value;
+ (NSNumber*)numberWithBool: (BOOL) value;
例:NSNumber *n = [NSNumber numberWithInt:5];

將基本類型數據封裝到NSNumber中後,就可以通過下面的實例方法重新獲取它:
- (char)charValue;
- (int)intValue;
- (float)floatValue;
- (BOOL)boolValue;
- (NSString*)stringValue;
例:int i = [n intValue];



資料來源:
http://www.quora.com/What-is-the-difference-between-NSInteger-NSNumber-int-and-all-the-different-ways-to-represent-an-integer
http://iosdevelopertips.com/cocoa/nsnumber-and-nsinteger.html
http://stackoverflow.com/a/5870916/3295047
http://stackoverflow.com/a/4445224/3295047
http://www.wuleilei.com/blog/335