在面向对象的编程语言中,值对象本质上是数据元素的的对象包装器,所谓数据元素,常见的包含string,number,date类型以及其它自定义的结构体类型。Objective-C语言本身提供了string,number,date相对应的包装类,分别是NSString,NSNumber,NSDate,这些类创建的对象都可以称为值对象。但值对象本身的范围更加广泛,它可以是任何自定义类型创建的对象。
1.处理NSRange,方法
+ (NSValue *)valueWithRange:(NSRange)range - (NSRange)rangeValue
如:
NSRange rangeA ; rangeA.location = 0 ; rangeA.location = 10 ; // 创建NSRange的值对象 NSValue *rangeValue = [NSValue valueWithRange:rangeA] ; // 重新获取值对象包含的值 NSRange rangeB = [rangeValue rangeValue] ; NSLog(@"%d,%d",rangeB.location , rangeB.length) ; // 10,10
2.处理自定义结构体类型,方法
+ (NSValue *)valueWithBytes:(const void *)value objCType:(const char *)type - (id)initWithBytes:(const void *)value objCType:(const char *)type - (void)getValue:(void *)buffer
如:
// 结构体定义 typedef struct{ int a ; float b ; }DataItem ; DataItem dataElemA ; dataElemA.a = 10 ; dataElemA.b = 10.005 ; NSValue *value = [NSValue valueWithBytes:&dataItem objCType:@encode(DataItem)] ; DataItem dataElemB ; [value getValue:&dataElemB] ; NSLog(@"%d,%0.3f",dataElemB.a,dataElemB.b); // 10,10.005
自定义类型必须是固定长度类型,不能将C字符串,可变长度的数组和结构体,以及其它变长类型存储在NSValue中,这些可变类型应该使用NSString或NSData来包装成对象类型。但可以将可变数据类型的指针保存在NSValue中,官方文档示例:
原意想要保存myCString到NSValue中,但实际上myCString是以char的指针类型进行解析的,所以字符串的前四个字节被当做了指针的值,而不是地址值来对待。
/* INCORRECT! */ char *myCString = "This is a string."; NSValue *theValue = [NSValue valueWithBytes:myCString objCType:@encode(char *)]; char *cc = (char*)malloc(sizeof(char*)*200) ; [theValue getValue:cc]; prinf("%s" , cc) ; // This free(cc)
正确的做法是保存字符串到NSString中,如,
char *myCString = "This is a string."; NSString myNsString = [NSString stringWithCString:myCString encoding:NSUTF8StringEncoding] ;
或者,保存该字符串的指针地址到NSValue中,如:
char *myCString = "This is a string."; NSValue *theValue = [NSValue valueWithBytes:&myCString objCType:@encode(char **)]; char **cc = (char**)malloc(sizeof(char**)*200) ; [theValue getValue:cc]; printf("----%s----" , *cc); // This is a string. free(cc) ; cc = NULL ;
3.处理指针类型,方法
+ (NSValue *)valueWithPointer:(const void *)aPointer - (void *)pointerValue 如: DataItem *dd = (DataItem*)malloc(sizeof(DataItem)) ; dd->a = 1 ; dd->b = 2 ; NSValue *pValue = [NSValue valueWithPointer:dd] ; DataItem *dc = (DataItem*)[pValue pointerValue] ; NSLog(@"%d,%0.3f",dc->a,dc->b); free(dd) ; dd = NULL ; dc = NULL ;
以CGPoint为例(其它的结构体都有相对应的方法),方法
+ (NSValue *)valueWithCGPoint:(CGPoint)point - (CGPoint)CGPointValue
如:
CGPoint origin = CGPointMake(10.0 , 10.0) ; NSValue *ptValue = [NSValue valueWithCGPoint:origin] ; NSArray *ptArr = [NSArray arrayWithObject:ptValue]; NSValue *ptValueB = [ptArr objectAtIndex:0] ; CGPoint originB = [ptValueB CGPointValue] ;
提供CATransform3D结构体的对象值包装
MapKit Additions
提供CLLocationCoordinate2D和MKCoordinateSpan结构体的对象包装