繼 NSNumber 之後,NSValue 是另一個重要的包裝類,它能封裝任意 C/C++ 類型,包括結構體、指針、類對象等。而 NSNull 則用於在集合中表示「空值」(區別於 nil)。本文詳細介紹兩者的用法與區別。
NSRange range = {1, 5}; // C 結構體
// 包裝:需指定類型編碼
NSValue *value = [NSValue value:&range withObjCType:@encode(NSRange)];
// 解包:需提供同類型變量接收
NSRange newRange;
[value getValue:&newRange];
// 輸出驗證
NSLog(@"%@", NSStringFromRange(newRange)); // 輸出 {1, 5}
@encode(類型) 編譯器生成類型的內部編碼字符串,NSValue 用它確定內存佈局。常見編碼:
| 類型 | @encode 結果示例 |
|---|---|
| int | i |
| float | f |
| NSRange | {NSRange=ii} |
| CGRect | {CGRect={CGPoint=dd}{CGSize=dd}} |
| 指針 | ^v |
| Class | # |
| SEL | : |
Foundation 為常用幾何結構體提供專用方法:
NSValue *pointVal = [NSValue valueWithCGPoint:CGPointMake(10, 20)]; NSValue *sizeVal = [NSValue valueWithCGSize:CGSizeMake(100, 50)]; NSValue *rectVal = [NSValue valueWithCGRect:CGRectMake(0, 0, 100, 100)]; NSValue *edgeVal = [NSValue valueWithUIEdgeInsets:UIEdgeInsetsMake(5, 5, 5, 5)]; NSValue *transVal = [NSValue valueWithCATransform3D:transform];
NSNull *null = [NSNull null]; // 單例,無需 alloc/init NSArray *arr = @[@"1", @"2", null, @"3"]; NSLog(@"arr = %@", arr); // 包含佔位符 // 判斷是否為空值 if ([arr[2] isKindOfClass:[NSNull class]]) { NSLog(@"第3個元素是空值佔位符"); } // JSON 解析常見場景 NSDictionary *json = @{@"name": @"Tom", @"age": [NSNull null]}; // age 字段存在但值為 null,區別於字段缺失
| 類 | 用途 | 可存類型 | 是否單例 |
|---|---|---|---|
| NSNumber | 包裝數值標量 | int, float, BOOL 等 | 否 |
| NSValue | 包裝任意類型 | 結構體、指針、類等任意 | 否 |
| NSNull | 表示集合中的空值 | 無(單例本身即語義) | 是 |
value:withObjCType: 和 getValue: 配對調用。