NSValue NSNumber NSData类

NSValue NSNumber NSData类

步骤1 NSValue

我们先看看NSValue能做什么:

一个NSValue对象是用来存储一个C或者Objective-C数据的简单容器。它可以保存任意类型的数据,比如 int,float,char,当然也可以是指pointer, structure, and object id。NSValue类的目标就是允许以上数据类型的数据结构能够被添加到集合里,例如那些需要其元素是对象的数据结构,如NSArray或者NSSet 的实例。需要注意的是NSValue对象一直是不可枚举的。

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

创建一个NSValue。

传递的参数是你想要包装的数值的地址(如一个NSSize或你自己的struct),通常得到的是你想要存储的变量的地址(在C语言中使用操作 符&)。你也可以提供一个用来描述这个数据类型的字符串(参数objCType),通常用来说明struct中实体的类型和大小。不需要自己写这 个字符串,@encode编译器指令可以接收数据类型的名称并生成合适的字符串。

2、- (void)getValue:(void *)value(出参);

从NSValue对象中提取数值。

提取的数值,存放在value这个指针所指向的内存块里。

3、Cocoa提供了常用struct数据类型转换成NSValue的便捷方法:

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

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

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

- (NSPoint)pointValue;

- (NSSize)sizeValue;

- (NSRect)rectValue;

NSRect是一个矩形数据种类,NSPoint是起始点,NSSize存储长度和宽度,这些常用的数据种类是C的struct而不是对象。

下边我们通过实验来认识NSValue的使用方式:

#import

int main (int argc, constchar * argv[])

{

@autoreleasepool {

//声明并初始化一个struct NSRectrtc = NSMakeRect(12, 32, 433, 343); //创建一个NSValue: NSValue *value = [NSValue valueWithBytes:&rtc objCType:@encode(NSRect)]; //把value添加到数组中 NSMutableArray *array = [NSMutable ArrayarrayWithCapacity:10]; NSRect rt; [array addObject:value];

的 //从数组中取到NSValue,因为只添加了一个,所以小标是0 NSValue *v = [array objectAtIndex:0]; //从value中取得一个NSRect,虽然返回值是void,但其实是它是利用指针返回值

[v getValue:&rt];

//输出结果 NSLog(@"%f %f %f %f", rt.origin.x, rt.origin.y, rt.size.height, rt.size.width); //用快速枚举遍历array并输出NSValue中struct属性的值 for(NSValue *v in array) { NSRect rt; [v getValue:&rt]; NSLog(@"%f %f %f %f", rt.origin.x, rt.origin.y, rt.size.height, rt.size.width); } /////////////////////便捷的struct转换成NAValue方式//////////////////////// //声明并初始化一个struct NSRect rtc1 = NSMakeRect(100, 200, 300, 400); //创建一个NSValue NSValue *value1 = [NSValue valueWithRect:rtc1]; //把value1添加到数组中 NSMutableArray *array1 = [NSMutable ArrayarrayWithCapacity:10];

[array1 addObject:value1];

NSRect rt1 = [value1 rectValue];

//输出结果

NSLog(@"%f %f %f %f", rt1.origin.x, rt1.origin.y, rt1.size.height, rt1.size.width);

}

} return 0;

注意:在集合中不能存放nil值,因为在NSArray和NSDictionary中nil有特殊的含义。但是在有些时候,确实需要用到这样的空 值,比如在字典中,电话簿中"Zhang San"关键字下有电话号码、家庭住址、Email等等信息,但是现在只知道他的电话号码,这种不知道其他信息

的情况下为了消除一些歧义,有必要将它们设置为空,所以Cocoa提供了NSNull

NSNull只有一个方法:null

[dictionarysetObject:[NSNull null], forKey:"Email"];

if(EmailAdress == [NSNull null])

{

} //to do something

NSNumber  将数据类型数字 封装到对象中

数值对象。

数值标量 -》 对象类型 的互转

基本类型(int,float等)转换为NSNumber NSNumber转换为基本类型(int,float等)

步骤2 NSNumber

NSNumber实际上是NSValue的子类,Cocoa提供了NSNumber类来包装(即以对象形式实现)基本数据类型。

例如以下创建方法:

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

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

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

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

创建对象后就可以放入字典或数组中。

将基本类型数据封装到NSNumber中后,可以通过下面的实例方法解除装箱,重新获取数据:

- (char) charValue;

- (int) intValue;

- (float) floatValue;

- (BOOL) boolValue;

- (NSString *) stringValue;

术语:将一个基本类型的数据包装成对象叫做装箱(boxing),从对象中提取基本类型的数据叫做取消装箱或拆箱(unboxing)。Objective-C不支持自动装箱。

下面我们通过实验程序掌握NSNumber的基本用法:

#import

int main (int argc, constchar * argv[])

{

@autoreleasepool { NSNumber *myNumber,*floatNumber,*intNumber,*number; //创建integer类型对象 intNumber = [NSNumber numberWithInteger:123]; NSLog(@"%i",[intNumber integerValue]); //创建long类型对象 myNumber = [NSNumber numberWithLong:0xababab]; NSLog(@"%lx",[myNumber longValue]); //创建char类型对象 myNumber = [NSNumber numberWithChar:‘K‘]; NSLog(@"%c",[myNumber charValue]); //创建float类型对象 floatNumber = [NSNumber numberWithFloat:123.00]; NSLog(@"%f",[floatNumber floatValue]); //创建double类型对象 myNumber = [NSNumber numberWithDouble:12345e+15]; NSLog(@"%lg",[myNumber doubleValue]); // Wrong access here NSLog(@"%i",[myNumber integerValue]); //判断两个对象的值是否相等 if ([intNumber isEqualToNumber:floatNumber] == YES ) { NSLog(@"值相等"); } else {

NSLog(@"值不相等"); }

//比较两个对象的值大小 if ( [intNumber compare:myNumber] == NSOrderedAscending) { NSLog(@"左边的数字小"); } else { } //初始化实例 NSLog(@"左边的数字大");

number = [[NSNumber alloc] initWithInt:1000];

NSLog(@"%i",[number intValue]);

[number release];

}

return 0;

}

注意:

(1)使用程序行myNumber = [NSNumber numberWithDouble: 12345e+15]; 创建double对象,然后尝试(不正确地)使用如下程序行来检索并显示它的值:

NSLog (@”%i”, [myNumber integerValue]);

将得到以下输出:

并且,系统也没有给出出错消息。一般来说,由程序员负责确保正确地进行检索,如果在NSNumber对象中存储了一个值,那么也要用一致的方式进行检索。

(2) NSNumber继承自NSObject,可以使用比较 compare:isEqualToNumber等消息。

(3)此外,还可以使用实例方法初始化NSNumber对象,这些都是以initWith开头,比如initWithInt。

number = [[NSNumber alloc] initWithInt:1000];

注意不能重新初始化前面创建的NSNumber对象的值。例如,不能使用下面的语句设置存储在NSNumber对象myNumber中的整数: [myNumber initWithInt: 1000];

当程序执行时,该条语句将产生一条错误。

步骤3 NSData

Cocoa中使用NSData类型来实现缓冲区,其实你可以把NSData当作JAVA 中的字节数组,用于存储二进制的数据类型,譬如:从网络下载回来的文件等。对于32位应用程序,NSData缓存区最多可以存储2GB的数据。

NSData的创建使用如下的类方法:

+(NSData*)dataWithBytes:(const void*) bytes length:(NSUInteger) length;

第一参数指定你要缓冲的数据的起始位置,也就是指针里存储的首地址,第二个参数指定数据的长度。例如:

#import

int main (int argc, constchar * argv[])

{

@autoreleasepool {

constchar *string="Hi,this is a c string";

//创建NSData对象 NSData *data=[NSData dataWithBytes:string length:strlen(string)+1]; NSLog(@"------%@",data); NSLog(@"length=%d,string=‘%s‘",[data length],[data bytes]); //将数据写入文件中

[data writeToFile:@"/Users/zhangkoumine/Desktop/myfile.txt"

atomically:TRUE];

}

return 0;

}

首先我们定义了一个C语言的字符序列,然后把它的指针、长度赋给了NSData的创建方法。这里需要注意的是由于C语言的字符序列的指针地址本身就 是数组的首地址,所以不需要再加&计算指针的地址了。另外,长度要再加1也是C语言的特性。C语言里的字符串以\0结尾。你会看到Shell窗口 输出一组16进制的数字,也就是缓冲区中存储的内容。NSData是长度不可变的数据缓冲区,还有一个NSMutableData用来存储长度可变的数据 缓冲区。 通常我们在进行文件的读写操作时会用到NSData类,将文件内容读入缓冲区或者将缓冲区的内容写入到一个文件。下面代码展示了如何将文件的内容读入内存 缓冲区,然后再将缓冲区的内容写入到另一个文件中。

例如读取testfile.txt文件中的数据,并将数据写到newfile.txt文件中。

#import

int main (int argc, constchar * argv[])

{

@autoreleasepool { NSFileManager * fm; NSData *fileData; fm = [NSFileManager defaultManager]; //读取文件testfile.txt 使用绝对路径 fileData = [fm contentsAtPath:@"/Users/zhangkoumine/Desktop/testfile.txt"]; if(fileData == nil) { NSLog(@"File read failed!"); return 1;

}

//将数据写到 newfile.txt (相当于拷贝文件)

if([fm createFileAtPath:@"/Users/zhangkoumine/Desktop/newfile.txt"

contents:fileData attributes:nil] == NO)

{

NSLog(@"Couldn‘t create the copy!");

return 2;

}

NSLog(@"File copy was successful!"); //读取拷贝后的文件 newfile.txt中的数据NSLog(@"%@",

[NSString stringWithContentsOfFile:@"/Users/zhangkoumine/Desktop/newfile.txt" encoding:NSUTF8StringEncoding error:nil]);

}

return 0;

}

在实际开发过程中,经常需要将NSData类型与其他类型进行转换。

1, NSData 与 NSString

//NSData --> NSString

NSString *aString = [[NSString alloc] initWithData:adata encoding:NSUTF8StringEncoding]; //NSString --> NSData

NSString *aString = @"1234";

NSData *aData = [aString dataUsingEncoding: NSUTF8StringEncoding];

2, NSData 与 Byte

//NSData --> Byte

NSString *testString = @"1234567890";

NSData *testData = [testString dataUsingEncoding: NSUTF8StringEncoding];

Byte *testByte = (Byte *)[testData bytes];

//Byte --> NSData

Byte byte[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23};

NSData *adata = [[NSData alloc] initWithBytes:byte length:24];

3, NSData 与 UIImage

//NSData --> UIImage

UIImage *aimage = [UIImage imageWithData: imageData];

//从本地文件沙盒中取图片并转换为NSData

NSString *path = [[NSBundle mainBundle] bundlePath];

NSString *name = [NSString stringWithFormat:@"ceshi.png"];

NSString *finalPath = [path stringByAppendingPathComponent:name];

NSData *imageData = [NSData dataWithContentsOfFile: finalPath];

UIImage *aimage = [UIImage imageWithData: imageData];

UIImage-> NSData

NSData *imageData = UIImagePNGRepresentation(aimae);

4, NSData 与 NSMutableData

//NSData --> MSMutableData

NSData *data=[[NSData alloc]init];

NSMutableData *mdata=[[NSMutableData alloc]init];

mdata=[NSData dataWithData:data];

5,NSData合并为一个NSMutableData

- (NSString *)filePathWithName:(NSString *)filename

{

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];

return [documentsDirectory stringByAppendingPathComponent:filename];

}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

//音频文件路径

NSString *mp3Path1 = [[NSBundle mainBundle] pathForResource:@"1" ofType:@"mp3"]; NSString *mp3Path2 = [[NSBundle mainBundle] pathForResource:@"2" ofType:@"mp3"]; //音频数据

NSData *sound1Data = [[NSData alloc] initWithContentsOfFile: mp3Path1];

NSData *sound2Data = [[NSData alloc] initWithContentsOfFile: mp3Path2];

//合并音频

NSMutableData *sounds = [NSMutableData alloc];

[sounds appendData:sound1Data];

[sounds appendData:sound2Data];

//保存音频

NSLog(@"data length:%d", [sounds length]);

[sounds writeToFile:[self filePathWithName:@"tmp.mp3"] atomically:YES];

[window makeKeyAndVisible];

return YES;

}

时间: 2024-10-06 07:11:59

NSValue NSNumber NSData类的相关文章

NSNumber,NSValue,NSData

参考博客 http://blog.csdn.net/yhawaii/article/details/8222973 http://blog.csdn.net/sakulafly/article/details/13292457 http://blog.csdn.net/at9009/article/details/7863720 我们在编码中,很多时候需要将C里面原生的数据封装成对象,这样可以用NSDictionary或者NSArray来存取访问.尤其是一些做适配的情况下,这种封装是不可避免的.

NSNumber,NSValue和NSData

我们在编码中,很多时候需要将C里面原生的数据封装成对象,这样可以用NSDictionary或者NSArray来存取访问.尤其是一些做适配的情况下,这种封装是不可避免的.Objective-C提供了不少类可以帮助我们,比较常见的是NSNumber,NSValue和NSData. NSNumber主要是用来封装ANSI C内置的数据,比如char,float,int等等.这个类提供了一批封装/解封的方法+ (NSNumber *)numberWithChar:(char)value;+ (NSNum

NSNumber,NSValue和NSData之间有什么区别?分别应用在什么地方?

我们在编码中,很多时候需要将C里面原生的数据封装成对象,这样可以用NSDictionary或者NSArray来存取访问.尤其是一些做适配的情况下,这种封装是不可避免的.Objective-C提供了不少类可以帮助我们,比较常见的是NSNumber,NSValue和NSData. NSNumber主要是用来封装ANSI C内置的数据,比如char,float,int等等.这个类提供了一批封装/解封的方法+ (NSNumber *)numberWithChar:(char)value;+ (NSNum

oc的包装类 NSValue NSNumber

我们都知道oc是面向对象的,但是oc是由c语言扩展而来的,c语言中的int 等类型都不是对象,那么oc 是如何拥有“对象”特征的呢? oc提供了NSValue 和 NSNumber 来封装c语言的基本类型,这样就具有来面向对象的特征了... NSValue是NSNumber的父类. NSValue代表更通用的包装类,可以包装 short int float char 对象id 指针  通过对这些的包装就可以添加到NSArray等集合中了: NSNumber代表更具体的包装类,主要有三个方法:(x

Objective-C基础夯实篇——NSValue&NSNumber(装箱和拆箱)

概述 NSNumber和NSValue都是用来做装箱用的,把基本类型的数据装成对象.官方文档给的资料说明地很清楚: /* NSValue.h Copyright (c) 1994-2014, Apple Inc. All rights reserved. */ #import <Foundation/NSObject.h> @class NSString, NSDictionary; @interface NSValue : NSObject <NSCopying, NSSecureCo

数值类对象:NSNumber,NSValue,NSNull

基本,集合,复杂,对象 可用对象封装基本数值,然后将对象放入NSArray或NSDictionary 中. 用对象封装基本数值后,即可给其发送消息. 数值类型包括:NSNumber,NSValue,NSNull类. oc不支持自动装箱 NSNumber类 创建方法 + (NSNumber *)numberWithChar:(char)value; + (NSNumber *)numberWithInt:(int)value; + (NSNumber *)numberWithFloat:(floa

OC学习篇之---Foundation框架中的其他类(NSNumber,NSDate,NSExcetion)

1.NSNumber 这个类主要是用来封装基本类型的,说到这里,就不得不说一下了: OC中的集合是不允许存入基本类型的,所以NSNumber类就诞生了,需要将基本类型封装一下,然后存进去,这个类似于Java中的自动装箱和拆箱,Java中的集合其实也是不允许存入基本类型的,但是我们任然看可以那么操作,就是因为有自动装箱功能,如果你将Eclipse的JDK改成5.0之前的,你看看还能操作吗.. 注:那为什么基本类型不能存入到集合中呢? 原因是在操作集合的时候会操作集合元素中的方法,但是基本类型是没有

Object - C 值对象 NSNumber和NSValue

在进行数据处理的时候,因为对象类型的不同, 并不能进行相应的数据处理,所以必须要进行数据类型的转换,这也就是NSNumber,NSValue这两类值对象出现的原因. 简而言之,NSNumber就是实现基本数据类型与对象类型的互相转换,而NSValue,则是实现结构体对象与对象类型的互相转换. NSNumber因为是实现基本数据类型与对象类型的互相转换,所以,必须是要有数据类型,而int ,char,BOOL,Float,Long,Integer等等等-都可以进行相应的转换 //1.将基本数据类型

黑马程序员--Foundation框架之--类其他常用的类:NSNumber,NSDate

------IOS培训期待与您交流! ------- Foundation的其他常用的类:NSNumber,NSDate 一.NSNumber 这个类主要是用来封装基本类型的,OC 中的集合是不允许存入基本类型的,所以NSNumber类就诞生了,需要将基本类型封装一下,然后存进去. 从这一点上我们就可以看出NSNumber是很重要的,后面一定会经常用到. 1.封包和解包 // 创建NSNumber // 封包 NSNumber *intNumber = [NSNumber numberWithI