bool转nsnumber ios_iOS 的 NSNumber(对基本数据类型) & NSValue(对结构体) 的装箱

int、 NSInteger、 NSUInteger、NSNumber之间的区别和联系

int : 当使用int类型定义变量的时候,可以像写C程序一样,用int也可以用NSInteger,推荐使用NSInteger ,因为这样就不用考虑设备是32位还是64位了。

NSUInteger是无符号的,即没有负数,NSInteger是有符号的。

NSInteger是基础类型,NSNumber是一个类,如果需要存储一个数值,直接使用NSInteger是不行的,比如在一个数组里使用下面的语句就会报错:

NSArray *array = [NSArray alloc] init];

[array addObject:3];

因为array里应该是一个类,但‘3’不是,所以需要用NSNumber:

NSArray *array = [NSArray alloc] init];

[array addObject:[NSNumber numberWithInt:3]];

装箱和拆箱

其实从上面的例子中我们也可以看到,数组和字典中只能存储对象类型,其他基本类型和结构体是没有办法放到数组和字典中的,当然你也是无法给它们发送消息的(也就是说有些NSObject的方法是无法调用的),这个时候通常会用到装箱(boxing)和拆箱(unboxing)。其实各种高级语言基本上都有装箱和拆箱的过程,例如C#中我们将基本数据类型转化为Object就是一个装箱的过程,将这个Object对象转换为基本数据类型的过程就是拆箱,而且在C#中装箱的过程可以自动完成,基本数据类型可以直接赋值给Object对象。但是在ObjC中装箱的过程必须手动实现,ObjC不支持自动装箱。

在ObjC中我们一般将基本数据类型装箱成NSNumber类型(当然它也是NSObject的子类,但是NSNumber不能对结构体装箱),调用其对应的方法进行转换:

+(NSNumber *)numberWithChar:(char)value;

+(NSNumber *)numberWithInt:(int)value;

+(NSNumber *)numberWithFloat:(float)value;

+(NSNumber *)numberWithDouble:(double)value;

+(NSNumber *)numberWithBool:(BOOL)value;

+(NSNumber *)numberWithInteger:(NSInteger)value;

拆箱的过程就更加简单了,可以调用如下方法:

-(char)charValue;

-(int)intValue;

-(float)floatValue;

-(double)doubleValue;

-(BOOL)boolValue;

简单看一个例子

//

// main.m

// FoundationFramework

//

// Created by Kenshin Cui on 14-2-16.

// Copyright (c) 2014年 Kenshin Cui. All rights reserved.

//

#import

/*可以存放基本类型到数组、字典*/

void test1(){

//包装类NSNumber,可以包装基本类型但是无法包装结构体类型

NSNumber *number1=[NSNumber numberWithChar:'a'];//'a'是一个C语言的char类型我们无法放倒NSArray中,但是我们可以通过NSNumber包装

NSArray *array1=[NSArray arrayWithObject:number1];

NSLog(@"%@",array1);

/*结果:

(

97

)

*/

NSNumber *number2= [array1 lastObject];

NSLog(@"%@",number2);//返回的不是基本类型,结果:97

char char1=[number2 charValue];//number转化为char

NSLog(@"%c",char1); //结果:a

}

int main(int argc, const char * argv[]) {

test1();

return 0;

}

上面我们看到了基本数据类型的装箱和拆箱过程,那么结构体呢?这个时候我们需要引入另外一个类型NSValue,其实上面的NSNumber就是NSValue的子类,它包装了一些基本数据类型的常用装箱、拆箱方法,当要对结构体进行装箱、拆箱操作我们需要使用NSValue,NSValue可以对任何数据类型进行装箱、拆箱操作。

事实上对于常用的结构体Foundation已经为我们提供好了具体的装箱方法:

+(NSValue *)valueWithPoint:(NSPoint)point;

+(NSValue *)valueWithSize:(NSSize)size;

+(NSValue *)valueWithRect:(NSRect)rect;

对应的拆箱方法:

-(NSPoint)pointValue;

-(NSSize)sizeValue;

-(NSRect)rectValue;

//

// main.m

// FoundationFramework

//

// Created by Kenshin Cui on 14-2-16.

// Copyright (c) 2014年 Kenshin Cui. All rights reserved.

//

#import

//NSNumber是NSValue的子类,而NSValue可以包装任何类型,包括结构体

void test1(){

CGPoint point1=CGPointMake(10, 20);

NSValue *value1=[NSValue valueWithPoint:point1];//对于系统自带类型一般都有直接的方法进行包装

NSArray *array1=[NSArray arrayWithObject:value1];//放倒数组中

NSLog(@"%@",array1);

/*结果:

(

"NSPoint: {10, 20}"

)

*/

NSValue *value2=[array1 lastObject];

CGPoint point2=[value2 pointValue];//同样对于系统自带的结构体有对应的取值方法(例如本例pointValue)

NSLog(@"x=%f,y=%f",point2.x,point2.y);//结果:x=10.000000,y=20.000000

}

int main(int argc, const char * argv[]) {

test1();

return 0;

}

那么如果是我们自定义的结构体类型呢,这个时候我们需要使用NSValue如下方法进行装箱:

+(NSValue *)valueWithBytes:(const void *)value objCType:(const char *)type;

调用下面的方法进行拆箱:

-(void)getValue:(void *)value;

//

// main.m

// FoundationFramework

//

// Created by Kenshin Cui on 14-2-16.

// Copyright (c) 2014年 Kenshin Cui. All rights reserved.

//

#import

typedef struct {

int year;

int month;

int day;

} Date;

//NSNumber是NSValue的子类,而NSValue可以包装任何类型,包括结构体

void test1(){

//如果我们自己定义的结构体包装

Date date={2014,2,28};

char *type=@encode(Date);

NSValue *value3=[NSValue value:&date withObjCType:type];//第一参数传递结构体地址,第二个参数传递类型字符串

NSArray *array2=[NSArray arrayWithObject:value3];

NSLog(@"%@",array2);

/*结果:

(

""

)

*/

Date date2;

[value3 getValue:&date2];//取出对应的结构体,注意没有返回值

//[value3 objCType]//取出包装内容的类型

NSLog(@"%i,%i,%i",date2.year,date2.month,date2.day); //结果:2014,2,28

}

int main(int argc, const char * argv[]) {

test1();

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值