标签:
1.NSDictionary初始化
乱入(有点扯淡):很少用通知,今天随手写了个通知传值,死活传不过去,打断点找了半天也没发现,最后是朋友发现了,发送和接收的通知名写的不一致。。。我也是醉,以后还是习惯性地把通知名抽成宏吧!!
Objective-C中,NSDictionary初始化的方法有很多种
方法1: [NSDictionary dictionaryWithObjectsAndKeys:<#(id), ...#>, nil] 方法2: NSDictionary *dic = @{@"key":value}
坑在哪里?
坑就在第二种初始化方法 NSDictionary *dic = @{@"key":value}
它到底是如何坑的呢?
如果你的value是为nil 必将引发崩溃:
‘NSInvalidArgumentException‘, reason: ‘*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]
意思就是说使用[__NSPlaceholderDictionary initWithObjects:forKeys:count:]这个初始化方法,发现keys count和objcects的个数不匹配了
如何规避?
在使用@{@”key”:value} 这种方式初始化的时候,一定要对value做是否为nil的判断,为nil就不要加入Dictionary
或
使用标准的初始化方法:
NSDictionary dictionaryWithObjectsAndKeys:value1,@"v1",value2,@"v2",value3,@"v3", nil];
或其它的几个初始化方法进行初始化,这样如果value为nil就不会加入字典,使用 objectForKey:取出来的对象就会为nil对象,不会引发崩溃。
关联:
使用@[]方法初始化NSArray也有此坑,规避方法同字典一样
2.字典转模型
之前写吐了的代码,用了MJExtension之后好久没写了。。
+ (instancetype)shopWithDict:(NSDictionary *)dict { DLShop *shop = [[self alloc] init]; [shop setValuesForKeysWithDictionary:dict]; return shop; }
或者
-(instancetype)initWithDict:(NSDictionary *)dict { if (self = [super init]) { [self setValuesForKeysWithDictionary:dict]; } return self; } + (instancetype)shopWithDict:(NSDictionary *)dict { return [[self alloc] initWithDict:dict]; }
在模型的.h文件里面提供属性接口和这两个实例化方法,在.m文件里实现他们
- (void)setValuesForKeysWithDictionary:(NSDictionary<NSString *, id> *)keyedValues;
上面方法的头文件: Given a dictionary containing keyed attribute values, to-one-related objects, and/or collections of to-many-related objects, set the keyed values. Dictionary entries whose values are NSNull result in -setValue:nil forKey:key messages being sent to the receiver.(有关NSNull)
今天遇到的坑,
崩在这里了,太年轻,找了半天,浪费不少时间,最终发现是模型的属性少写了一个,如上图,字典里面有八个键值对,模型属性只有5个。(至于为什么会发生如下的无线调用导致内存崩溃,尚不得知-_-!)总之在这里模型属性只能多不能少!模型属性只能多不能少!模型属性只能多不能少!重要的事情要说三遍
用
- (void)setValuesForKeysWithDictionary:
这个方法还需要注意一点,字典里面的键值(key)必须和属性名一一对应(一样),遇到id。。等关键字时:
由于属性很多。手工写setvalue太麻烦
- (void)setValue:(id)value forUndefinedKey:(NSString *)key { if([key isEqualToString:@"id"]) self.userid = value;
这时只需要重写- (void)setValue:(id)value forUndefinedKey:(NSString *)key 方法即可
并把声明 中的id改为userid
@property (nonatomic,strong) NSString *userid;
这样一来执行程序快速,还省去了不少手工代码。
- (void)setValue:(id)value forUndefinedKey:(NSString *)key { if([key isEqualToString:@"id"]) { key = @"shop_id"; } [super setValue:value forKey:key]; // [super setValue:value forUndefinedKey:key];应该是上面的,敲的时候看着点 }
或者像上面那样
- (void)setValue:(id)value forUndefinedKey:(NSString *)key { if([key isEqualToString:@"id"]) { self.shop_id = value; } }
对于我现在常用的MJExtension,顺带也在这里记一笔:
比较常用的
控制器中引用#import "MJExtension.h"
模型数组 = [模型类名 objectArrayWithFilename:@"文件名.plist"];
使用方法:在模型类的.m文件中,引用#import "MJExtension.h"
在@implementation 和 @end之间,写上MJLogAllIvrs
使用方法:在模型类的.m文件中,引用#import "MJExtension.h"
在@implementation 和 @end之间,写上MJCodingImplementation
4.1 场景一: [ 字典1,
字典2,
字典3 ]
如果每个字典都是一个模型,可以用
NSArray *modelArray = [模型类名 objectArrayWithKeyValuesArray:字段数组];
4.2 场景二:在场景一的基础上,每个字典里面,有数组(假设数组的key值是arrayName),数组里面存放着若干个相同的模型,使用下面的方法
使用方法:
首先在模型类.m文件中,引入#import "MJExtension.h"
然后在 @implementation 和 @end之间 写上
- (NSDictionary *)objectClassInArray { return @{@"arrayName" : [模型类名 class]}; }
使用replacedKeyFromPropertyName
使用方法:1.在模型类.m文件引入"MJExtension.h"
2.实现方法
+ (NSDictionary *)replacedKeyFromPropertyName { return @{@“非关键字的属性名” : @“数组的key”}; }
+ (instancetype)objectWithKeyValues:(NSDictionary *)keyValues
公司的旧项目里面用的Mantle,github上星星爆表的牛B框架,(但是忘的差不多了,0.0.。。MJ大神在一天就用它了,MJExtension)这里附上南峰子大神的关于mantle的博客链接,大神的博客值得学习
第一篇就写到这,都是小问题,太年轻,后续应该陆续会有很多类似篇,主要是自己增强印象,大神见谅。。。。
标签:
原文地址:http://www.cnblogs.com/mysticCoder/p/5049806.html