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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...