原 IOS之NSValue整理
在面向对象的编程语言中,值对象本质上是数据元素的的对象包装器,所谓数据元素,常见的包含string,number,date类型以及其它自定义的结构体类型。Objective-C语言本身提供了string,number,date相对应的包装类,分别是NSString,NSNumber,NSDate,这些类创建的对象都可以称为值对象。但值对象本身的范围更加广泛,它可以是任何自定义类型创建的对象。
值对象作用
C语言提供了char/int/float/double基本数据类型,基于C语言的Objective-C因此同样包含了这几种基本数据类型,我们可以定义并使用这些基本数据类型的变量,也可以使用其对应的值对象,对于自定义数据类型,我们也可以将由这些类型定义的变量通过NSValue来包装成对象类型。相对于普通的变量,值对象提供了更多的功能和作用。
1.可将任何值对象存储在集合中。
在Objective-C中,诸如NSArray,NSDictionary这样的集合类所包含的元素必须是对象类型。因此基本数据类型的变量必须转换为值对象才能存储在集合中。
2.更加更加丰富的数据处理方法。
NSString或NSMulableString可以进行一系列针对字符串的操作,如字符串的连接,分割,查找,比较,提取字符等等。
NSDate和NSCaleder可进行复杂的日期处理和计算,所有这些计算都考虑了时区和闰年的影响。
NSNumber和NSDecimalNumber可以处理 char, short int, int, long int, long long int, float, or double , BOOL值,并提供了数值与字符串的转换
NSValue释义
上面我们已经提到NSValue可包装基本数据类型为对象类型,下面我们来看下Apple官方文档释义:
NSValue提供了简单的容器来包含C或Objective-C数据项。可以容纳任何基本数据类型如char,int,float,double,以及指针,结构体和对象ids。NSArray和NSSet集合类对象要求它们的元素为对象类型,NSValue的主要目的是使这些数据类型可以添加至集合中。NSValue对象是不可变类型。
简而言之,NSValue是基本数据类型或自定义数据类型所定义变量的对象包装器。
使用NSValue
1.处理NSRange,方法
1
2
|
+ (NSValue *)valueWithRange:(NSRange)range - (NSRange)rangeValue |
如,
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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.处理自定义结构体类型,方法
1
2
3
|
+ (NSValue *)valueWithBytes:( const void *)value objCType:( const char *)type - (id)initWithBytes:( const void *)value objCType:( const char *)type - ( void )getValue:( void *)buffer |
如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
// 结构体定义 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的指针类型进行解析的,所以字符串的前四个字节被当做了指针的值,而不是地址值来对待。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
/* 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中,如,
1
2
3
|
char *myCString = "This is a string." ; NSString myNsString = [NSString stringWithCString:myCString encoding:NSUTF8StringEncoding] ; |
或者,保存该字符串的指针地址到NSValue中,如,
1
2
3
4
5
6
7
8
9
10
11
12
13
|
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.处理指针类型,方法
1
2
|
+ (NSValue *)valueWithPointer:( const void *)aPointer - ( void *)pointerValue |
如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
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 ; |
NSValue的分类
提供了Function框架中关于几何数据类型结构体的对象值包装,包括CGPoint,CGRect,CGSize,CGAffineTransform,UIEdgeInsets,UIOffset。
以CGPoint为例(其它的结构体都有相对应的方法),方法
1
2
|
+ (NSValue *)valueWithCGPoint:(CGPoint)point - (CGPoint)CGPointValue |
如:
1
2
3
4
5
6
7
8
9
|
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] ;
|
原 IOS之NSValue整理的更多相关文章
- 原 iOS面试题收集
原 iOS面试题收集 发表于2年前(2013-07-22 13:47) 阅读(369) | 评论(0) 4人收藏此文章, 我要收藏 赞0 听云性能监测产品App.Server.CDN免费试用,绑定 ...
- iOS面试题整理带答案
iOS面试题整理带答案 找工作,面试是避免不了的! 而技术开发面试,问一些技术相关的问题是必须的,最新的技术可能人人都趋之若鹜,但有些原理和基础的也希望都有了解. 这里整理了一些iOS相关 ...
- iOS 学习资料整理
iOS学习资料整理 https://github.com/NunchakusHuang/trip-to-iOS 很好的个人博客 http://www.cnblogs.com/ygm900/ 开发笔记 ...
- 原 iOS深入学习(Block全面分析)http://my.oschina.net/leejan97/blog/268536
原 iOS深入学习(Block全面分析) 发表于1年前(2014-05-24 16:45) 阅读(26949) | 评论(14) 39人收藏此文章, 我要收藏 赞21 12月12日北京OSC源创会 ...
- 兼容iOS 10 资料整理笔记
原文链接:http://www.jianshu.com/p/0cc7aad638d9 1.Notification(通知) 自从Notification被引入之后,苹果就不断的更新优化,但这些更新优化 ...
- IOS UI 笔记整理回顾
注意手势会冒泡上抛,一个view没有实现的手势,如果父类view有实现,父视图就处理,如果不想让父视图处理,就把本视图添加到底层window上 setMasksToBounds:YES imageVi ...
- iOS 视频播放方式整理
初衷 多媒体这整个系列的文章自己也准备好开始整理了,先从视频音频最简单也是最常用的播放出发慢慢的往下深究,探索到底层的编码解码等等,这篇文章就从视频的播放这个最简单的说起. iOS的视频播放方式有几种 ...
- 关于新版本,iOS10的相关内容,兼容iOS 10 资料整理笔记
1.Notification(通知) 自从Notification被引入之后,苹果就不断的更新优化,但这些更新优化只是小打小闹,直至现在iOS 10开始真正的进行大改重构,这让开发者也体会到UserN ...
- iOS 面试题整理(带答案)二
第一篇面试题整理: http://www.cocoachina.com/bbs/read.php?tid-459620.html 本篇面试题同样:如答案有问题,欢迎指正! 1.回答person的ret ...
随机推荐
- bzoj3673 bzoj3674可持久化并查集
并查集都写不来了qwq 之前写的是错的 sz的初值都是0,这样怎么加就都是0了,水这道题还是可以,但是加强版就过不了了 #include<cstdio> #include<cstri ...
- AIX操作oracle
oracle:出现下述错误,无法连接用户. ORA-01034: ORACLE not available ORA-27101: shared memory realm does not exist ...
- 20169210《Linux内核原理与分析》第三周作业
本次作业也是分为两部分,第一部分是对实验楼<Linux基础入门>复习,第二部分为对课本18章的复习. 第一次学习实验楼的<Linux基础入门>时由于是第一次接触Linux,所以 ...
- win8 64位 mysql安装 Configuration file my.ini error code -1
问题如题,解决方法: 1.由于目录中纯在中文,所以导致代码错误.故而把目录设置成全英文的. 2.下载64位mysql安装,安装32位mysql也会出现此问题.
- PHP拦截器的使用(转)
PHP有如下几个拦截器: 1.__get($property)功能:访问未定义的属性是被调用2.__set($property, $value)功能:给未定义的属性设置值时被调用3.__isset($ ...
- CHAR 详解
CHAR(20):20指的是表中的a字段能存储的最大字符个数 CREATE TABLE `a` ( `a` char(20) DEFAULT NULL) ENGINE=InnoDB DEFAULT C ...
- hadoop小文件合并
1.背景 在实际项目中,输入数据往往是由许多小文件组成,这里的小文件是指小于HDFS系统Block大小的文件(默认128M), 然而每一个存储在HDFS中的文件.目录和块都映射为一个对象,存储在Nam ...
- ASP.NET MVC 中 ActionResult 和 ViewResult 在使用上的区别
如果确认你返回的是一个视图(view),你可以直接返回类型为ViewResult. 如果你并不是很清楚,或者你根本不想去理解这些东西,你可以直接返回ActionResult
- 未能加载文件或程序集“Newtonsoft.Json, Version=4.5.0.0[已解决]
在使用百度UEditor,不小心将Newtonsoft.Json,升级了,然后就报的一个错,说: 其他信息: 未能加载文件或程序集“Newtonsoft.Json, Version=4.5.0.0, ...
- 实用脚本 - - insertAfter 在现有元素后插入一个新元素
function insertAfter(newElement,targetElement){ var parent = targetElement.parentNode; if(parent.las ...