NSValue
一、NSValue 、 NSNumber、 NSDecimalNUmber 关系与作用
1、由于集合里只能存放对象,不可以存放基础类型,所有我们有时候需要将一些比如基本数据类型,结构体等存放到NSDictionary、NSArray中,我们就需要将这些数据类型或结构体包装成OC对象,以便集合能访问到。常用的用来包装这些类型的有NSNumber、 NSValue。
2、NSNumber只能包装基本数据类型,比如int、float、char、BOOL等。
3、NSValue可以包装任意一个对象,包装系统自定义的数据结构,结构体等。
4、NSNumber是NSValue的一个子类。
5、NSDecimalNUmber是NSNumber的一个子类。
二、
1) NSNumber
实例1:
//包装
int age =20;
NSNumber *num = [NSNumbernumberWithInt:age];//将基本数据类型int对象age包装成NSNumber对象
num = @(age);//直接包装
//拆封
[num intValue];
2) NSValue
实例1:
//将结构体包装成OC对象
CGPoint point =CGPointMake(10,20);
NSValue *value = [NSValuevalueWithCGPoint:point];//将结构体point包装成NSValue对象
//拆
[value pointerValue];
实例2:
//定义一个简单的结构体类型Student
typedefstruct {
NSInteger age;
float height;
float score;
unsignedchar flag;
}Student;
//对结构体进行封装
Student phoebe;
phoebe.age =23;
phoebe.height =1.57;
phoebe.score =9;
phoebe.flag ='A';
NSValue *value = [NSValuevalueWithBytes:&phoebe objCType:@encode(Student)];//对结构体进行封装
NSLog(@"Phoebe的年龄 = %zd,身高 = %f, flag = %c", phoebe.age, phoebe.height, phoebe.flag);
//输出 Phoebe的年龄 = 23,升高 = 1.570000, flag = A
//取出value中的数据,如下:
Student xiaoping;//声明xiaoping,为了得到phoebe的值
[value getValue:&xiaoping];//同类型赋值
NSLog(@"xiaoping的年龄 = %zd, 身高 = %f, flag = %c", xiaoping.age, xiaoping.height, xiaoping.flag);
//输出 xiaoping的年龄 = 23,升高 = 1.570000, flag = A
实例3:
/**
对于NSValue类的使用,还可以用在iPhone上显示点或者其他几何图形时。如:我们想取得用户在屏幕上点击的轨迹,使用CGPoint这个结构体保存每一次点击的数据。此时,我们就可以使用NSValue类别中的+ (NSValue *)valueWithCGPoint:方法来帮助我们来为CGFramework提供数据。
*/
//1.NSValue包装指针
NSValue* start = [NSValuevalueWithPointer:@selector(start:)];
NSValue* help = [NSValuevalueWithPointer:@selector(help:)];
//NSArray 添加NSValue包装后的指针
NSArray *pointerArray = [[NSArrayalloc] initWithObjects:start, help,nil];
CGRect rect1 = {10,10, 200,200};
CGRect rect2 = {20,20, 100,100};
//2.NSValue包装CGRect结构
NSValue *aRect1 = [NSValuevalueWithCGRect:rect1];
NSValue *aRect2 = [NSValuevalueWithCGRect:rect2];
//NSArray 添加NSValue包装后的指针
NSArray *rectArray = [[NSArrayalloc] initWithObjects:aRect1, aRect2,nil];
//3.CGAffineTransform
CGAffineTransform transform1 =CGAffineTransformMakeRotation(40);
CGAffineTransform transform2 =CGAffineTransformMakeRotation(-40);
NSValue *aTransform1 = [NSValuevalueWithCGAffineTransform:transform1];
NSValue *aTransform2 = [NSValuevalueWithCGAffineTransform:transform2];
NSArray *transArray = [[NSArrayalloc] initWithObjects:aTransform1, aTransform2,nil];
[self.pickerButtonsetFrame:[[rectArray objectAtIndex:0]CGRectValue]];
[self.pickerButtonsetTransform:[[transArrayobjectAtIndex:0]CGAffineTransformValue]];
[selfperformSelector:[[pointerArrayobjectAtIndex:0]pointerValue] withObject:nilafterDelay:0.5];
==================================================================================================
NSValue
一个NSValue对象是用来存储一个C或者Objective-C数据的简单容器。它可以保存任意类型的数据,比如int,float,char,当然也可以是指pointers, structures, and object ids。NSValue类的目标就是允许以上数据类型的数据结构能够被添加到集合里,例如那些需要其元素是对象的数据结构,如NSArray或者NSSet的实例。需要注意的是NSValue对象一直是不可枚举的。
1) Foundation
#import <Foundation/NSObject.h>
@class NSString,NSDictionary;
NS_ASSUME_NONNULL_BEGIN
@interface NSValue :NSObject <NSCopying,NSSecureCoding>
- (void)getValue:(void *)value;
@property (readonly)const char *objCTypeNS_RETURNS_INNER_POINTER;
- (instancetype)initWithBytes:(constvoid *)value objCType:(constchar *)type NS_DESIGNATED_INITIALIZER;
- (nullableinstancetype)initWithCoder:(NSCoder *)aDecoderNS_DESIGNATED_INITIALIZER;
@end
@interface NSValue (NSValueCreation)创建
+ (NSValue *)valueWithBytes:(constvoid *)value objCType:(constchar *)type;
+ (NSValue *)value:(constvoid *)value withObjCType:(constchar *)type;
@end
@interface NSValue (NSValueExtensionMethods)扩展方法
+ (NSValue *)valueWithNonretainedObject:(nullableid)anObject;
@property (nullable,readonly) id nonretainedObjectValue;
+ (NSValue *)valueWithPointer:(nullableconst void *)pointer; //保存对象指针
@property (nullable,readonly) void *pointerValue;
- (BOOL)isEqualToValue:(NSValue *)value;
@end
2) UIKit
@interface NSValue (NSValueUIGeometryExtensions)
+ (NSValue *)valueWithCGPoint:(CGPoint)point; //保存CGPoint结构体
+ (NSValue *)valueWithCGVector:(CGVector)vector;
+ (NSValue *)valueWithCGSize:(CGSize)size; //保存CGSize结构体
+ (NSValue *)valueWithCGRect:(CGRect)rect; //保存CGRect结构体
+ (NSValue *)valueWithCGAffineTransform:(CGAffineTransform)transform;
+ (NSValue *)valueWithUIEdgeInsets:(UIEdgeInsets)insets; //保存UIEdgeInsets结构体
+ (NSValue *)valueWithUIOffset:(UIOffset)insetsNS_AVAILABLE_IOS(5_0);
#if UIKIT_DEFINE_AS_PROPERTIES
@property(nonatomic,readonly) CGPoint CGPointValue;
@property(nonatomic,readonly) CGVector CGVectorValue;
@property(nonatomic,readonly) CGSize CGSizeValue;
@property(nonatomic,readonly) CGRect CGRectValue;
@property(nonatomic,readonly) CGAffineTransform CGAffineTransformValue;
@property(nonatomic,readonly) UIEdgeInsets UIEdgeInsetsValue;
@property(nonatomic,readonly) UIOffset UIOffsetValueNS_AVAILABLE_IOS(5_0);
#else
- (CGPoint)CGPointValue;
- (CGVector)CGVectorValue;
- (CGSize)CGSizeValue;
- (CGRect)CGRectValue;
- (CGAffineTransform)CGAffineTransformValue;
- (UIEdgeInsets)UIEdgeInsetsValue;
- (UIOffset)UIOffsetValue NS_AVAILABLE_IOS(5_0);
#endif
@end