KVC和KVO的簡單對比

来源:http://www.cnblogs.com/leiming1001/archive/2016/02/08/leiming001.html
-Advertisement-
Play Games

一、對於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];
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、dos命令安裝mysqld --stall、啟動net start mysql、進入MySQL資料庫mysql -uroot -p後,輸入select user();當前用戶 select current_date();當前日期 select current_time();當前時間 select
  • 1、dos命令安裝mysqld --stall、啟動net start mysql、進入MySQL資料庫mysql -uroot -p後,輸入select database(); 如圖:
  • 問題描述: 使用nmp install express -g命令全局安裝express後,在終端使用express -V命令可以獲取到express的版本號,但在引用express的項目運行時,會報缺少express的錯誤,如下圖 解決方案: 在配置文件/etc/profile中添加Node的路徑
  • 1、考慮這樣一個場景。 我們的程式中有一個“選項”視窗,這個視窗包含很多選項。其中有一個選項是單選類型的,用戶可以從N個選項值中選擇一個。 我們需要在用戶單擊“確定”按鈕後把用戶選擇的值保存到文件中,程式下次啟動時再讀取到記憶體中。 2、不好的解決方案 通常情況下,我們會在按鈕單擊事件中寫類似下麵的代
  • 第三篇博客, 這次說的是插入鏈接類標簽, 我們平常在網頁中經常能看到藍色的鏈接類標簽, 或者是一張圖片, 一個電郵, 這些都是插入鏈接類的標簽起的作用. <a></a>鏈接標簽 <a>鏈接標簽可實現超鏈接, 它在網頁中是無處不在的, 只要有鏈接的地方, 就會有這個標簽, 它的語法和其他的標簽不太相同
  • $http服務允許我們與服務端交互,有時候我們希望在發出請求之前以及收到響應之後做些事情。即http攔截。$httpProvider包含了一個interceptors的數組。我們這樣創建一個interceptor。 app.factory('myInterceptor', ['$log', func
  • 筆記信息 複習: 表單作用: 從使用的角度上說:html提供了一個輸入內容的途徑。 從伺服器的角度:提供了一個收集信息的途徑。 以便客戶端和伺服器進行交互。 例:註冊頁面,上傳文件。 3種常見元素:input select textarea Input的十種常見類型: text,password,r
  • 今天就是一個網頁的入門,說實話我不太想當前端工程師。因為 那些東西 不會按照我的想法來實現對應的效果。我只想做一個大概。我想做後端開發。如果能是伺服器端就很happy。如果能有 android的部分 就很happy。 然後現在就只是單單來寫一些對應屬性就好: 1、基本屬性: <font> 字體標簽,
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...