一、對於KVC模式(Key Value Coding): 1、其實在實際開發中用得比較多得就是:接收到json數據之後,通過解析,解析成NSDictionary,然後再把字典對應的欄位建立一個Model,在Model裡面自定義一個類方法+(instancetype)modelWithDictiona
一、對於KVC模式(Key Value Coding):
1、其實在實際開發中用得比較多得就是:接收到json數據之後,通過解析,解析成NSDictionary,然後再把字典對應的欄位建立一個Model,在Model裡面自定義一個類方法+(instancetype)modelWithDictionary:(NSDictionary *)keyDictionary方法中調用
?1 |
[self setValuesForKeysWithDictionary:jsonObject];
|
從而達到我們想要的效果,將字典裝成Model。
2、然後對於一些想要特殊處理的欄位可以調用以下方法來進行特殊處理,比如裡面有些key是字典類型,則可以通過以下方式搞定:
?1 2 3 4 5 6 7 8 9 10 11 |
-( void ) setValue:(id)value forKey:(NSString *)key
{
if ([key isEqualToString:@ "products" ])
{
for (NSMutableDictionary *productDict in value)
{
Prodcut *product = [[Product alloc] initWithDictionary:prodcutDict];
[self.products addObject:product];
}
}
}
|
3、還有一種情況,就是裡面的Key壓根就沒定義,可以通過重寫以下這個方法來重新把key和value對應上號:
?1 2 3 4 5 6 7 8 9 |
- ( void )setValue:(id)value forUndefinedKey:(NSString *)key
{
if ([key isEqualToString:@ "nameXXX" ])
self.name = value;
if ([key isEqualToString:@ "ageXXX" ])
self.age = value;
else
[super setValue:value forKey:key];
}
|
二、對於KVO模式(Key-Value Observing):
KVO概述:
KVO,即:Key-Value Observing,它提供一種機制,當指定的對象的屬性被修改後,則對象就會接受到通知。
簡單的說就是每次指定的被觀察的對象的屬性被修改後,KVO就會自動通知相應的觀察者了。
KVO的優點:
當有屬性改變,KVO會提供自動的消息通知。這樣開發人員不需要自己去實現這樣的方案:每次屬性改變了就發送消息通知。
這是KVO機制提供的最大的優點。因為這個方案已經被明確定義,獲得框架級支持,可以方便地採用。
開發人員不需要添加任何代碼,不需要設計自己的觀察者模型,直接可以在工程里使用。
其次,KVO的架構非常的強大,可以很容易的支持多個觀察者觀察同 一個屬性,以及相關的值。
使用步驟如下:
1. 註冊,指定被觀察者的屬性,
2. 實現回調方法
3. 觸發回調方法
4. 移除觀察
KVO使用例子代碼如下:
###############Model(模型)###############
#import <Foundation/Foundation.h>
@interface Music : NSObject {
// 監聽的屬性
NSString *musicName;
}
@end
#import "Music.h"
@implementation Music
@end
###############ViewController(視圖控制器)###############
#import <UIKit/UIKit.h>
@class Music;
@interface ViewController : UIViewController {
Music *music;
}
@property (nonatomic, retain) Music *music;
@end
@implementation ViewController
@synthesize music;
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
music = [[Music alloc] init];
// 添加觀察者 註冊當屬性發生改變的時候被調用的
[music addObserver:self forKeyPath:@"musicName" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
// UILabel控制項
UILabel *musicLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 150, 280, 21)];
musicLabel.font = [UIFont fontWithName:@"ArialMT" size:18];
musicLabel.textColor = [UIColor redColor];
musicLabel.tag = 100;
[self.view addSubview:musicLabel];
[musicLabel release];
// UITextField控制項
UITextField *musicTextField = [[UITextField alloc] initWithFrame:CGRectMake(20, 200, 280, 21)];
musicTextField.font = [UIFont fontWithName:@"ArialMT" size:18];
musicTextField.placeholder = @"Please enter some words.";
musicTextField.backgroundColor = [UIColor whiteColor];
// UITextField輸入內容時候調用
[musicTextField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
[self.view addSubview:musicTextField];
[musicTextField release];
self.view.backgroundColor = [UIColor grayColor];
}
- (void)textFieldDidChange:(id)sender {
UITextField *textField = (UITextField *)sender;
NSLog(@">>>>>>>>>>>>>>>%@",textField.text);
// 修改正在監聽的屬性,將調用下麵回調方法
[music setValue:textField.text forKey:@"musicName"];
}
// 只要Music類的"musicName"屬性發生的變化都會觸發到以下的方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
UILabel *label = (UILabel *)[self.view viewWithTag:100];
// 如果改變的屬性是"musicName"
if ([keyPath isEqualToString:@"musicName"]) {
// 將 當前的musicName屬性的值 賦值給UILabel
label.text = [music valueForKey:@"musicName"];
// 輸出改變前的值
NSLog(@"old musicName is %@",[change objectForKey:@"old"]);
// 輸出改變後的值
NSLog(@"new musicName is %@",[change objectForKey:@"new"]);
}
}
#pragma mark - Memory Management
- (void)dealloc {
// 移除觀察者
[music removeObserver:self forKeyPath:@"musicName"];
[music release];
[super dealloc];
}