zoukankan      html  css  js  c++  java
  • 原 IOS之NSValue整理

    原 IOS之NSValue整理

    发表于2年前(2013-02-28 23:02)   阅读(1974) | 评论(0) 5人收藏此文章, 我要收藏
    3

    值对象(value object)概念

            在面向对象的编程语言中,值对象本质上是数据元素的的对象包装器,所谓数据元素,常见的包含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的分类 

    UIKit Additions 

            提供了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] ;

     

  • 相关阅读:
    八数码难题 (codevs 1225)题解
    小木棍 (codevs 3498)题解
    sliding windows (poj 2823) 题解
    集合删数 (vijos 1545) 题解
    合并果子 (codevs 1063) 题解
    等价表达式 (codevs 1107)题解
    生理周期 (poj 1006) 题解
    区间 (vijos 1439) 题解
    区间覆盖问题 题解
    种树 (codevs 1653) 题解
  • 原文地址:https://www.cnblogs.com/iOS-mt/p/4106624.html
Copyright © 2011-2022 走看看