NSArray和NSDictionary只能存储对象,而不能直接存储任何基本类型的数据,如int 、float、或struct。但是你可以用对象来封装基本数值。例如,将int 型数据封装到一个对象中,然后就可以将这个对象放入NSArray或NSDictionary中了。Cocoa提供了NSNumber类来包装基本数据类型 .但是 对于结构体,指针这些复杂的数据类型NSNumber没有办法把它们存储为对象,怎么办呢?有句话叫儿子不行,老爹出马,NSvalue是NSNumber的父类,NSValue可以把任意类型包装成对象。
下面我们把一个结构体包装成对象
typedef struct
{
int year;
int month;
int day;
}Date;
void value2()
{
Date date = {2013, 4, 7};
//根据结构体类型生成对应的类型描述字符串
char *type = @encode(Date);
NSValue *value = [NSValue value:&date withObjCType:type];//第一个参数传入一个对象的地址表示你要存储数据的地址 第二个参数传入一个描述即将要存储的数据类型的字符串,用@encode编译器指令接收数据类型的名称并生成合适的字符串。
例如:
NSLog(@"%s",@encode(int));
NSLog(@"%s",@encode(float));
NSLog(@"%s",@encode(struct sct));
//定义一个结构体变量
Date date1;
//取出包装好的结构体
[value getValue:&date1];//这样value中存储的数据就传到date1中了
NSLog(@"%d %d %d",date1.year,date1.month,date1.day);
}
char * p = (char *)0x1f;
NSValue *value = [[NSValue alloc]initWithBytes:&p objCType:@encode(char *)];
char *q;
[value getValue:&q];
NSLog(@"%p",q);
再举些NSValue包装的对象的例子:
CGPoint point = CGPointMake(10, 10);
CGSize size;
CGRect rect = CGRectMake(1, 2, 320, 480);
//将CGPoint用NSValue包装起来
NSValue *pointValue = [NSValue valueWithPoint:point];
//将CGPoint添加进数组
NSMutableArray *array = [NSMutableArray array];
[array addObject:value];
//取出放进去的value
NSValue *value1 = [array lastObject];
CGPoint point1 = [value1 pointValue];
//验证取出来的point1 跟之前的point是不是完全一样
BOOL result = CGPointEqualToPoint(point, point1);
NSLog(@"result = %i",result);
NSValue *sizeValue = [NSValue valueWithSize:size];
NSValue *range = [NSValue valueWithRange:NSMakeRange(3,4)];
NSValue *rectValue = [NSValue valueWithRect:rect];
CGRect newRect;
[rectValue getValue:&newRect];
NSLog(@"%f %f",newRect.size.width,newRect.size.height);