Foundation之-字典、拆装箱、反射

1.字典操作

1.1字典的初始化操作有以下几种方法:

1)通过普通的key-value进行单个的初始化。
2)通过key-value集进行初始化。
3)通过value数组和key数组进行初始化
4)系统底层封装的最简单轻便的一种初始化方式
代码:

void testDict()
{
    /** 字典的初始化 */
    // 1.通过简单的单个value--key进行初始化
    NSDictionary *dict1 = [NSDictionary dictionaryWithObject:@"1" forKey:@"a"];
    NSLog(@"%@",dict1);
    /* 结果: { a = 1; } */

    // 2.通过key--value集合进行初始化
    NSDictionary *dict2 = [NSDictionary dictionaryWithObjectsAndKeys:
                          @"1",@"a",
                          @"2",@"b",
                          @"3",@"c",
                          nil];
    NSLog(@"%@",dict2);
    /* 结果: { a = 1; b = 2; c = 3; } */

    // 3.通过value数组和key数组进行初始化
    NSDictionary *dict3 = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"1",@"2",@"3",nil] forKeys:[NSArray arrayWithObjects:@"a",@"b",@"c", nil]];
    NSLog(@"%@",dict3);
    /* 结果: { a = 1; b = 2; c = 3; } */
    // 4.最方便的一种初始化方式
    NSDictionary *dict4 = @{@"1":@"a",@"2":@"b",@"3":@"c",@"4":@"d"};
    NSLog(@"%@",dict4);
    /* 结果: { 1 = a; 2 = b; 3 = c; 4 = d; } */
}

1.2字典的遍历

1.最普通庸俗的遍历方法。
2.通过key进行遍历。
3.通过迭代器进行遍历。
4.通过block进行遍历。
代码:

void testDictRes()
{
    NSDictionary *dict1 = [NSDictionary dictionaryWithObjectsAndKeys:
                           @"1",@"a",
                           @"2",@"b",
                           @"3",@"c",
                           @"2",@"d",
                           nil];
    /** 从字典中取值 */
    NSLog(@"%zi",[dict1 count]);
    NSLog(@"%@",[dict1 valueForKey:@"b"]); // 根据键值取得结果为2
    NSLog(@"%@",dict1[@"b"]); // 同上,只是形式不同
    NSLog(@"%@,%@",[dict1 allKeys],[dict1 allValues]);  // 取得字典中的所有key和所有value
    NSLog(@"*************************");

    /** 遍历字典 */
    // method1: 通过key遍历字典
    for(id key in dict1){
        NSLog(@"%@=%@",key,[dict1 objectForKey:key]);
    }
    NSLog(@"-------------------------");

    // method2: 通过迭代器遍历字典
    NSEnumerator *enumerator = [dict1 keyEnumerator]; // 返回有值的迭代器
    id key = nil;
    while (key = [enumerator nextObject]) {
        NSLog(@"%@=%@",key,[dict1 objectForKey:key]);
    }
    NSLog(@"-------------------------");

    // method3: 通过block遍历字典
    [dict1 enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
        NSLog(@"%@=%@",key,obj);
    }];
}

2.拆装箱

概述:
在其它编程语言中也有拆箱装箱机制,像java中是自动拆箱和装箱的。所谓的拆箱和装箱是 这样解释的(java中):因为编程语言中有基本类型和引用类型,所以把基本类型转化为引用类型这一过程就叫做装箱;而从引用类型转化为基本类型就是拆箱。

OC中的没有自动拆箱和装箱机制,所以需要我们进行手动的拆箱和装箱。OC中的拆箱和装箱分为几种情况:
1)对于OC中的基本数据类型,比如int,float,double,char等直接使用NSNumber进行装箱。形如如下方法:

+(NSNumber *)numberWithChar:(char)value;
+(NSNumber *)numberWithInt:(int)value;
+(NSNumber *)numberWithFloat:(float)value;
+(NSNumber *)numberWithDouble:(double)value;
+(NSNumber *)numberWithBool:(BOOL)value;
+(NSNumber *)numberWithInteger:(NSInteger)value;

拆箱过程相对比较简单:

-(char)charValue; -(int)intValue; -(float)floatValue; -(double)doubleValue; -(BOOL)boolValue;

2)对于OC语言中自带的结构体进行装箱和拆箱时需要使用NSValue类。
3)对于自己定义的结构体变量如何进行装箱和拆箱时需要用的NSVaue类的一下方法进行。
装箱:+ (NSValue *)valueWithBytes:(const void*)value objCType:(const char*)type;
拆箱:- (void)getValue:(void *)value;

代码:

/** 自动拆箱与装箱 */
void testBox()
{
    // 对于系统自带的结构体用NSValue进行自动的装箱
    CGPoint point1 = CGPointMake(10, 20);
    NSValue *value1 = [NSValue valueWithPoint:point1]; // 对于系统自带的类型,一般都有直接包装的方法
    NSArray *array1 = [NSArray arrayWithObject:value1]; // 放到数组中
    NSLog(@"%@",array1);

    NSValue *value2 = [array1 lastObject];
    CGPoint point2 = [value2 pointValue];
    NSLog(@"x=%f,y=%f",point2.x,point2.y);

    // 对于自己定义的结构体变量需要用NSValue的如下方法进行自动的拆箱和装箱
    // 装箱: + (NSValue *)valueWithBytes:(const void*)value objCType:(const char*)type;
    // 拆箱: - (void)getValue:(void *)value;
    typedef struct{
        int year;
        int month;
        int day;
    } Date;
    Date date = {2015,9,18};
    char *type = @encode(Date);
    NSValue *value3 = [NSValue value:&date withObjCType:type]; // 第一个参数传递结构体地址,第二个参数传递类型字符串
    NSArray *array2 = [NSArray arrayWithObject:value3];
    NSLog(@"%@",array2);
    /* 结果: ( "<df070000 09000000 12000000>" ) */

    Date date2;
    [value3 getValue:&date2]; // 取出对应的结构体,该方法没有返回值
    NSLog(@"%i-%i-%i",date2.year,date2.month,date2.day);
    /* 结果: 2015-9-18 */


    /** * 数组和字典都是以nil结尾的,但是如果我们想往数组中存储nil值,而不是作为结束标记该如何处理? * 此时我们利用到的就是NSNull,该类是一个单例,只有一个null方法 */
    NSNull *n1 = [NSNull null];
    NSNull *n2 = [NSNull null];
    NSLog(@"%i",n1 == n2); // 是单例,所以结果为1

    NSArray *array3 = [NSArray arrayWithObjects:@"abc",n1,@123,nil];
    NSLog(@"%@",array3);
    /* 结果: ( abc, "<null>", 123 ) */
}

3.反射

代码:

/** 反射 */
void testReflect()
{
    Person *person1 = [Person personWithName:@"QiZhang"];
    NSLog(@"%i",[person1 isKindOfClass:[NSObject class]]); // 判断一个对象是否为某种类型 结果:1

    NSLog(@"%i",[person1 isMemberOfClass:[NSObject class]]); // 判断某一个对象是否是某个类的实例化对象 结果:0
    NSLog(@"%i",[person1 isMemberOfClass:[Person class]]); // 结果:1

    NSLog(@"%i",[person1 conformsToProtocol:@protocol(NSCopying)]); // 是否实现了某个协议 结果:0

    NSLog(@"%i",[person1 respondsToSelector:@selector(showMessage:)]); // 是否存在某个方法


    /** 反射 */
    // 动态生成一个类
    NSString *className = @"Person";
    Class myClass = NSClassFromString(className); // 根据类名生成类
    Person *person2 = [[myClass alloc] init];
    person2.name = @"Aven";
    NSLog(@"%@",person2); // 结果: name = Aven

    NSLog(@"%@,%@",NSStringFromClass(myClass),NSStringFromClass([Person class])); // 类转化成字符串 结果: Person,Person

    // 调用方法
    NSString *methodName = @"showMessage:";
    SEL mySelector = NSSelectorFromString(methodName);
    Person *person3 = [[myClass alloc] init];
    person3.name = @"Rosa";
    [person3 performSelector:mySelector withObject:@"Hello,wrld!"];  // 结果:结果:My name is Rosa,the infomation is "Hello,world!".

    // 方法转化为字符串
    NSLog(@"%@",NSStringFromSelector(mySelector)); // 结果:showMessage:

}

你可能感兴趣的:(代码,数组,Foundation)