還是老樣子,先翻譯KVC
** KVC:Key Value Coding (鍵值編碼)**
作用:
- KVC可以用來訪問和設置實例變量的值( key為屬性名)
- KVC很暴力,可以訪問私有屬性或者私有變量,但是這個變量必須是以 _打頭才可以(這篇文章不演示,因為不常用)
還是老樣子,直接上代碼:
首先我們先創建一個model,這里以Student為例,在.m文件中重寫description方法(方便調試)
#import <Foundation/Foundation.h>
@interface Student : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *sex;
@end
#import "Student.h"
@implementation Student
- (NSString*)description {
return [NSString stringWithFormat:@"\nname:%@\nsex:%@",self.name,self.sex];
}
@end
新建command line項目(也是方便調試),這篇文章主要示例Dictionary轉model
#import <Foundation/Foundation.h>
#import "Student.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
NSDictionary* dic = @{
@"name":@"爪",
@"sex":@"true",
};
Student* model = [Student new];
[model setValuesForKeysWithDictionary:dic];
NSLog(@"%@",model);
}
return 0;
}
運行看到以下結果
** 下面試試其他情況 **
** 情況1: **先在在Student類中新增一個age屬性
#import <Foundation/Foundation.h>
@interface Student : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *sex;
@property (nonatomic, copy) NSString *age;
@end
#import "Student.h"
@implementation Student
- (NSString*)description {
return [NSString stringWithFormat:@"\nname:%@\nsex:%@\nage:%@",self.name,self.sex,self.age];
}
@end
運行:
運行是沒有問題的,_age變量值為null
** 情況2: **字典擴充一個 @"address":@"USA"
運行:
崩潰了
控制臺報的錯也是很容易懂的,這里就不翻譯了,主要說一下解決辦法
這個時候我們可以這樣解決
在Student類中增加 - (void)setValue:(id)value forUndefinedKey:(NSString *)key;
@interface Student : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *sex;
@property (nonatomic, copy) NSString *age;
- (void)setValue:(id)value forUndefinedKey:(NSString *)key;
@end
在.m文件中實現這個方法
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
NSLog(@"沒有這個 %@ key",key);
}
自己可以運行看結果哈,不會再崩潰了
** KVC 官方API **
Foundation框架下,NSKeyValueCoding
** 情況3: ** 服務器返回的json中含有id這樣的key
當服務器放回給這樣的key的話,個人建議還是不要用,(我們項目中這樣用了,暫時沒發現問題,但是還是建議不要這樣用)因為id是OC的關鍵字,可以這樣改:(這邊用大寫的ID)
@interface Student : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *sex;
@property (nonatomic, copy) NSString *age;
@property (nonatomic, copy) NSString *ID;
- (void)setValue:(id)value forUndefinedKey:(NSString *)key;
@end
.m文件中
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
if ([key isEqualToString:@"id"]) {
self.ID = value;
}
}
好的設計:
如果我們每個model都去- (void)setValue:(id)value forUndefinedKey:(NSString *)key; 豈不是很麻煩
這個時候我們可以創建一個model父類,在這個父類中去處理這樣的邏輯,然后自己創建的model繼承父類model就ok了
希望會給大家帶來幫助(o)/~