KVC,字典转模型 & 泛型数组

来源:互联网 发布:ie6修复软件 编辑:程序博客网 时间:2024/05/21 17:50

字典转模型 & 泛型数组

  • 开发中,为了简化控制器和视图中的代码编写,通常是不针对字典直接操作的。
  • 为了简化程序员的开发,苹果提供了 KVC(key value coding) 技术
  • KVC 又被称为苹果开发的大招

目标

  • 掌握 KVC 的字典转模型和模型转字典方法
    • 字典转模型 setValuesForKeysWithDictionary
      • 使用自定的字典转换成模型
      • 使用细节:
        • 如果字典中有对象中不存在的 key,会崩溃
        • 如果对象属性中有字典中不存在的 key,没有反应
        • 本质上就是遍历字典 key,然后一个一个的设置数值
  • 模型转字典 dictionaryWithValuesForKeys

    • 使用指定的属性列表,将模型转换成字典
  • 注意:字典转模型和模型转字典,默认都只能转换一级模型,嵌套模型还需要增加代码

  • 有关 KVC 字典转模型的实现原理,后续课程会讲
  • 掌握代码块定义技巧

    • ~/Developer/Xcode/UserData/CodeSnippets
    • 不需要的代码块直接选中按删除键可以删除
  • 掌握数组泛型的使用技巧,Xcode 7 提供

    • 数组是以下标来访问内部元素的
    • 尽管 OC 中的数组可以存放任意对象,但是一个数组中保存的元素类型通常是一致的
    • 在定义泛型数组时,可以增加 <类 *> 的格式指定数组内部存放元素的类型
    • 格式:NSMutableArray <Person *>*arrayM
    • 指定了类型之后:
      • 如果向数组中添加其他类型的对象会报警告,提前发现错误
      • 可以直接通过 . 语法获取数组内部元素的属性
      • 控制台不支持 . 语法,仍然需要使用 []

操作步骤

准备模型 —— 代码块演练

由于是复习知识点,中间穿插一下定义代码块,提高开发效率的技巧

  • 新建 Person 模型继承自 NSObject
  • 定义模型属性
@interface Person : NSObject@property (nonatomic, copy) NSString *name;@property (nonatomic, assign) NSInteger age;@end

介绍代码块定义

  • 定义模型构造函数
#pragma mark - 模型构造函数+ (instancetype)personWithDict:(NSDictionary *)dict;- (instancetype)initWithDict:(NSDictionary *)dict;

演示构造函数的代码块定义

介绍代码块维护

  • 不需要的代码块直接选中按删除键可以删除
  • 保存位置

    • ~/Developer/Xcode/UserData/CodeSnippets
  • 复制备课代码块

实现构造函数,介绍 KVC 的两个大招

  • 字典转模型 setValuesForKeysWithDictionary,简化开发
  • 模型转字典 dictionaryWithValuesForKeys,简化调试
  • 在 ViewController 中导入头文件
#import "Person.h"
  • 在 viewDidLoad 方法中实例化模型并且测试
- (void)viewDidLoad {    [super viewDidLoad];    NSDictionary *dict = @{@"name": @"zhangsan", @"age": @18};    Person *p1 = [Person personWithDict:dict];    NSLog(@"%@ %@ %zd", p1, p1.name, p1.age);}
  • 传统的设置方法
+ (instancetype)personWithDict:(NSDictionary *)dict {    return [[self alloc] initWithDict:dict];}- (instancetype)initWithDict:(NSDictionary *)dict {    self = [super init];    if (self) {        // 方法 1,直接设置,基本数据类型需要转换        _name = dict[@"name"];        _age = [dict[@"age"] integerValue];    }    return self;}
  • 使用 KVC 设置属性
- (instancetype)initWithDict:(NSDictionary *)dict {    self = [super init];    if (self) {        // 1. 方法 1 直接设置数值//        _name = dict[@"name"];//        _icon = dict[@"icon"];        // 方法 2 使用 KVC 设置数值        [self setValue:dict[@"name"] forKey:@"name"];        [self setValue:dict[@"icon"] forKey:@"icon"];    }    return self;}
  • 方法 3,遍历字典 设置数值
// 方法 3,遍历字典 设置数值for (NSString *key in dict) {    id value = dict[key];    [self setValue:value forKey:key];}
  • setValuesForKeysWithDictionary
// 方法 4,简化方法[self setValuesForKeysWithDictionary:dict];
  • setValuesForKeysWithDictionary 方法,本质上就是遍历字典
  • 然后依次调用 [self setValue:value forKey:key]; 设置数值

实现 description 简化调试

  • 默认情况下,实例化一个对象之后,打印只能输出对象的类型和指针
  • 为了方便程序的开发调试,在定义模型是通常建议实现一下 description
- (NSString *)description {    NSArray *keys = @[@"name", @"age"];    return [self dictionaryWithValuesForKeys:keys].description;}
  • dictionaryWithValuesForKeys 方法会遍历给定的 keys 数组
  • 顺序取出每一个 key 对应属性的 value
  • 依次添加到字典中

在开发模型时,实现 description 是一个好习惯

泛型数组

  • 数组是以下标来访问内部元素的
  • 尽管 OC 中的数组可以存放任意对象,但是一个数组中保存的元素类型通常是一致的
  • 在定义泛型数组时,可以增加 <类 *> 的格式指定数组内部存放元素的类型
  • 格式:NSMutableArray <Person *>*arrayM
  • 指定了类型之后:

    • 如果向数组中添加其他类型的对象会报警告,提前发现错误
    • 可以直接通过 . 语法获取数组内部元素的属性
    • 控制台不支持 . 语法,仍然需要使用 []
  • 示例代码

NSMutableArray <Person *>*arrayM = [NSMutableArray array];NSDictionary *dict1 = @{@"name": @"zhangsan", @"age": @18};NSDictionary *dict2 = @{@"name": @"lisi", @"age": @108};[arrayM addObject:[Person personWithDict:dict1]];[arrayM addObject:[Person personWithDict:dict2]];NSLog(@"%@", arrayM[1].name);
0 0
原创粉丝点击