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;
}
NSValue NSNumber NSData类的更多相关文章
- NSNumber,NSValue和NSData
我们在编码中,很多时候需要将C里面原生的数据封装成对象,这样可以用NSDictionary或者NSArray来存取访问.尤其是一些做适配的情况下,这种封装是不可避免的.Objective-C提供了不少 ...
- NSString,NSArray,NSNumber等类的继承问题
问题引入,我想给NSString类扩展一些新的方法.在Objective-C中可以有两种方法,一是继承,二是类别.本文先不讨论类别,我们用继承的方法试一下: @interface StringEx : ...
- NSValue&NSNumber
void testForNSValue(void) { int i=10; // NSLog(@"encode(int)=%s",@encode(int)); // N ...
- OC NSNumber和NSValue和NSDate和NSData
一 NSNumber // // main.m // 07-NSNumber // // Created by apple on 13-8-12. // Copyright (c) 2013年 itc ...
- 数值类对象:NSNumber,NSValue,NSNull
基本,集合,复杂,对象 可用对象封装基本数值,然后将对象放入NSArray或NSDictionary 中. 用对象封装基本数值后,即可给其发送消息. 数值类型包括:NSNumber,NSValue,N ...
- Objective - C 值对象 NSNumber和NSValue
在进行数据处理的时候,因为对象类型的不同, 并不能进行相应的数据处理,所以必须要进行数据类型的转换,这也就是NSNumber,NSValue这两类值对象出现的原因. 简而言之,NSNumber就是实现 ...
- NSNumber和NSValue
在进行数据处理的时候,因为对象类型的不同, 并不能进行相应的数据处理,所以必须要进行数据类型的转换,这也就是NSNumber,NSValue这两类值对象出现的原因. 简而言之,NSNumber就是实现 ...
- (转载)OC学习篇之---Foundation框架中的其他类(NSNumber,NSDate,NSExcetion)
前一篇说到了Foundation框架中的NSDirctionary类,这一一篇来看一下Foundation的其他常用的类:NSNumber,NSDate,NSException. 注:其实按照Java ...
- 转:用法总结:NSNumber、NSString、NSDate、NSCalendarDate、NSData(待续)
NSNumber + (NSNumber *)numberWithInt:(int)value; + (NSNumber *)numberWithDouble:(double)value; - (in ...
随机推荐
- 【OpenCV入门教程之一】 安装OpenCV:OpenCV 3.0、OpenCV 2.4.8、OpenCV 2.4.9 +VS 开发环境配置
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/19809337 作者:毛星云(浅墨 ...
- 关于PHP程序使用file_get_content()函数进行抓取PHP程序与smarty结合编译过程中产生的静态文件,抓取不了?连接超时?(地址映射)
问题: 当file_get_content()函数的参数 url中是localhost时不能抓取,是127.0.0.1时可以抓取到静态html代码.实现页面静态化技术提高访问效率. test.php ...
- 移动开发框架,第【二】弹:Hammer.js 移动设备触摸手势js库
hammer.js是一个多点触摸手势库,能够为网页加入Tap.Double Tap.Swipe.Hold.Pinch.Drag等多点触摸事件,免去自己监听底层touchstart.touchmove. ...
- linux 命令c语言代码实现
自己学习<APUE>时写的linux下一些命令(大概40个左右)实现,仅当学习使用,这些命令包含cat cp echo head ls paste rmdir tail umask who ...
- JavaScript的变量提升
在JavaScript中,var变量具有函数级作用域,而且是整个函数作用域.为什么会是整个函数作用域呢?因为var变量具有变量(声明)提升功能,能将变量声明隐式的提升到函数体的顶部.这样做的一个好处就 ...
- Android开发:最详细的 Toolbar 开发实践总结
最详细的 Toolbar 开发实践总结 过年前发了一篇介绍 Translucent System Bar 特性的文章 Translucent System Bar 的最佳实践,收到很多开发者的关注和反 ...
- C# 日期字符串转成javascript日期
1.c# date to js date var csharpStr='/Date(1479694396330)/'; //替换掉非数字 csharpStr=csharpStr.replace(/[^ ...
- 绝对炫的幻灯片插件-SKITTER
绝对炫的幻灯片插件-SKITTER 所属分类:媒体-幻灯片和轮播图,图片展示,滑块和旋转 Includes code source // Styles <link href="css/ ...
- Shell - 特殊变量
$0 表示所执行程序的路径名. [huey@huey-K42JE ~]$ ll ~/bin total 4 -rwxrwxr-x 1 huey huey 21 Oct 24 14:39 hello [ ...
- OpenGL ES 3.0 点,线,三角形绘制形式总结
OpenGL ES 3.0 顶点 -1, 1, 0, -0.5f, 0, 0, 0, -1, 0, -1, 0, 0, 0.5f, 0, 0, 1, -1, ...