在 Objective-C 中,集合類別(NSArray、NSDictionary、NSSet)只能儲存物件(id 類型),無法直接存放 int、float、BOOL 等基本資料類型。NSNumber 正是為了解決這一問題而設計的不可變值物件封裝類別。本文整理了 NSNumber 的完整介面、建構方法與實際應用場景。
NSNumber 繼承自 NSValue,提供豐富的數值型別封裝與轉換功能:
- (char)charValue;
- (unsigned char)unsignedCharValue;
- (short)shortValue;
- (unsigned short)unsignedShortValue;
- (int)intValue;
- (unsigned int)unsignedIntValue;
- (long)longValue;
- (unsigned long)unsignedLongValue;
- (long long)longLongValue;
- (unsigned long long)unsignedLongLongValue;
- (float)floatValue;
- (double)doubleValue;
- (BOOL)boolValue;
- (NSInteger)integerValue; // NS_AVAILABLE(10_5, 2_0)
- (NSUInteger)unsignedIntegerValue; // NS_AVAILABLE(10_5, 2_0)
- (NSString *)stringValue; // 取得字串表示
- (NSComparisonResult)compare:(NSNumber *)otherNumber;
- (BOOL)isEqualToNumber:(NSNumber *)number;
- (NSString *)descriptionWithLocale:(id)locale;
分為實例方法(initWith...)與類別方法(numberWith...),涵蓋所有常見基本類型:
- (id)initWithChar:(char)value;
- (id)initWithUnsignedChar:(unsigned char)value;
- (id)initWithShort:(short)value;
- (id)initWithUnsignedShort:(unsigned short)value;
- (id)initWithInt:(int)value;
- (id)initWithUnsignedInt:(unsigned int)value;
- (id)initWithLong:(long)value;
- (id)initWithUnsignedLong:(unsigned long)value;
- (id)initWithLongLong:(long long)value;
- (id)initWithUnsignedLongLong:(unsigned long long)value;
- (id)initWithFloat:(float)value;
- (id)initWithDouble:(double)value;
- (id)initWithBool:(BOOL)value;
- (id)initWithInteger:(NSInteger)value; // NS_AVAILABLE(10_5, 2_0)
- (id)initWithUnsignedInteger:(NSUInteger)value; // NS_AVAILABLE(10_5, 2_0)
+ (NSNumber *)numberWithChar:(char)value;
+ (NSNumber *)numberWithUnsignedChar:(unsigned char)value;
+ (NSNumber *)numberWithShort:(short)value;
+ (NSNumber *)numberWithUnsignedShort:(unsigned short)value;
+ (NSNumber *)numberWithInt:(int)value;
+ (NSNumber *)numberWithUnsignedInt:(unsigned int)value;
+ (NSNumber *)numberWithLong:(long)value;
+ (NSNumber *)numberWithUnsignedLong:(unsigned long)value;
+ (NSNumber *)numberWithLongLong:(long long)value;
+ (NSNumber *)numberWithUnsignedLongLong:(unsigned long long)value;
+ (NSNumber *)numberWithFloat:(float)value;
+ (NSNumber *)numberWithDouble:(double)value;
+ (NSNumber *)numberWithBool:(BOOL)value;
+ (NSNumber *)numberWithInteger:(NSInteger)value; // NS_AVAILABLE(10_5, 2_0)
+ (NSNumber *)numberWithUnsignedInteger:(NSUInteger)value; // NS_AVAILABLE(10_5, 2_0)
NSArray *numbers = @[
@42, // NSNumberLiteral (Clang 3.1+)
[NSNumber numberWithInt:100],
[NSNumber numberWithDouble:3.14159],
[NSNumber numberWithBool:YES]
];
for (NSNumber *num in numbers) {
NSLog(@"Value: %@, Int: %ld, Double: %f", num, num.longValue, num.doubleValue);
}
NSDictionary *userInfo = @{
@"age": @25,
@"score": @98.5,
@"isVip": @YES
};
NSInteger age = [userInfo[@"age"] integerValue];
BOOL isVip = [userInfo[@"isVip"] boolValue];
NSNumber *a = @10;
NSNumber *b = @20;
NSComparisonResult result = [a compare:b]; // NSOrderedAscending
NSArray *scores = @[@85, @92, @78, @96];
NSArray *sorted = [scores sortedArrayUsingSelector:@selector(compare:)];
// sorted: @78, @85, @92, @96
NSNumber 物件一旦建立即不可修改,所有「修改」操作實際上會產生新實例。int 存入卻用 doubleValue 取出可能導致精度誤解;建議統一使用 numberWith... 工廠方法配合 integerValue/doubleValue。@42、@3.14、@YES 字面量語法,等同於對應的 numberWith... 呼叫,程式碼更簡潔。NSNumber 是 Objective-C 基本類型與物件體系之間的橋樑,掌握其完整介面與現代寫法(字面量、標記指標),能讓集合操作、數值計算、資料序列化更加高效安全。實際開發中,優先使用 @(...) 字面量語法與工廠方法,善用 compare: 進行排序比較,並注意 64 位元環境下的標記指標優化特性。