1. 程式人生 > >關於 KVO 和 KVC 的一些總結 以及使用KVC進行字典和模型的互相轉換

關於 KVO 和 KVC 的一些總結 以及使用KVC進行字典和模型的互相轉換

一直對KVO 和KVC都是停留在 只是知道的情況,從來沒有嘗試這在專案中使用,最近準備總結一下,在專案裡面簡單的使用一下

1、什麼是KVO?

KVO其實就是Key-Value-Observer,也就是鍵值觀察者,是基於KVC機制實現的另一種模式。也許有不少同學用過SVPullToRefresh或者MJRefresh重新整理元件,都使用了KVO來實現。

看了一下感覺kvo有些地方和通知有一些相同的地方,因此在有時候可以使用KVO來代替通知,

舉個栗子,

在當前VC裡面,當另外一個dataModel類中的某個屬性變化時,我需要即時的得到dataModel變化的資訊,並且得到所變化的值,這個時候使用鍵值觀察者模式就非常方便了

下面為dataModel類:

#import <Foundation/Foundation.h>
#import "KVOClass.h"

@interface Student : NSObject

@property(nonatomic) NSString *studentName;
@property (nonatomic) float grade;
@property(nonatomic)KVOClass *kvoClass;

@end

設定一秒之後改變  資料模型中的 屬性  studentName的值,

-(void)changename{
    self.studentName 
[email protected]
"學生的名字改為+++老王了"; [selfsetValue:@"學生的名字改為+++老王了"forKey:@"studentName"]; }


VC裡面,dataModel類的物件新增一個觀察者來檢測

這樣只要model類屬性發生變化,這邊既可以得到通知,實現對應的邏輯功能即可,一般做資料的更新比較方便。。。

#import "KVOClass.h"
#import "Student.h"
#import "Teacher.h"

@implementation KVOClass


- (instancetype)init
{
    self = [super init];
    if (self) {
         self.student= [[Student alloc]init];
        self.teacher = [[Teacher alloc]init];
        
        //某一物件本身新增 本類物件 為觀察者
        [self addObserver:self   forKeyPath:@"name" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:@"name"];
        //某一物件新增本類物件為觀察者
        [self.student  addObserver:self    forKeyPath:@"studentName"  options:0|1context:nil];
        
        //某一物件新增其他類物件為觀察者
        [self.student   addObserver:self.teacher    forKeyPath:@"studentName"  options:0|1context:nil];
        
    }
    return  self;
}


實現收到通知的方法;哪個類 新增觀察者 ,哪個類就負責實現這個方法

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
    if (context == @"name") {
        NSLog(@"%@",self.name);
    }else if ([keyPath isEqualToString:@"studentName"]){//回撥方法必須處理,否則會crash掉!!!!!!!
         NSLog(@"本類物件++++%@",self.student.studentName);
    }else {
        [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

下面是在其他類Teacher中處理回撥函式的情況

/****

 change  通知回撥的引數,包含所檢測物件的值的變化  change[@"new"]即可取到

注意!!!  change[@"new"]取到的值全是物件資料型別,沒有基本資料型別的(如果是 int float等,得到的是NSNumber型別)

同樣的  kvc的時候賦值的時候也要是物件型別,基本型別資料要轉成物件型別的

 *****/


-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
    if ([keyPath isEqualToString:@"studentName"]) {
        NSLog(@"老師貌似收到了學生資訊改變的通知了,+++%@",change[@"new"]);
    }else if ([keyPath isEqualToString:@"grade"]){
      NSLog(@"老師貌似收到了學生資訊改變的通知了,+++%@",change[@"new"]);
    }
}


移除觀察者, 哪個類 新增觀察者 ,哪個類就負責移除觀察者
-(void) dealloc
{
    [self removeObserver:self forKeyPath:@"name"];
    [self.student removeObserver:self forKeyPath:@"studentName"];
    [self.student removeObserver:self.teacher forKeyPath:@"studentName"];
    [self.student removeObserver:self.teacher forKeyPath:@"grade"];

}


總結一下:

//總結   1、誰成為觀察者,誰就要實現收到通知的回撥方法,可以在當前類(新增觀察者的類),也可以在觀察者的類中去實現,

//      2、新增觀察者與移除觀察者是成對出現的,一定要記得移除,原則是在那個類新增就在那個類移除觀察者。否則會crash!!!

//      3、某一物件可以添加當前類的物件為觀察者,也可以新增其他類的物件為觀察者,

                                                                                                    。                                                                              KVC和字典轉模型

 //******************  使用 KVC 自動字典轉模型 ******************//
    NSDictionary *dic = @{@"name":@"cheng",@"nick":@"laocheng",@"addr":@"henan",@"phone":@(10086),@"test":@"false"};

    Student *student = [[Student alloc]init];
    [student setValuesForKeysWithDictionary:dic];   // 使用 KVC 自動字典轉模型,實體類只有宣告一下屬性,此方法可以自動把字典的key
                                                    //和value 分別賦給 實體
//    /如果kvc轉模型的時候 傳的字典裡面的key如果沒有對應屬性的key時,會自動呼叫此方法
//    -(void)setValue:(id)value forUndefinedKey:(NSString *)key{
    NSLog(@"phone : %@",student.phone);
    
     //******************  使用 KVC 自動模型轉字典 ******************//
    NSDictionary *dict = [student dictionaryWithValuesForKeys:@[@"name",@"nick",@"addr",@"phone"]];
    NSLog(@"dict : %@",dict);

資料模型
@interface Student : NSObject
@property(nonatomic)NSString *name;
@property(nonatomic)NSString *nick;
@property(nonatomic)NSString *addr;
@property(nonatomic)NSNumber *phone;
@property(nonatomic)NSString *testProperty;

@end


相關推薦

關於 KVO KVC一些總結 以及使用KVC進行字典模型互相轉換

一直對KVO 和KVC都是停留在 只是知道的情況,從來沒有嘗試這在專案中使用,最近準備總結一下,在專案裡面簡單的使用一下 1、什麼是KVO? KVO其實就是Key-Value-Observer,也就是鍵值觀察者,是基於KVC機制實現的另一種模式。也許有不少同學用過SV

C++ const static的總結以及使用

局部變量 數值 功能 const 常量 指針 main this指針 同名 this 一 static的使用 (作用域和存儲方式) 1.作用域---------->隱藏 靜態函數跟靜態全局變量的作用類似 (靜態函數不能被其它文件所用; 其它文件中可以定義相同名字的函

Java反射註解一些總結

Java 反射和註解的一些總結 反射 // There are five kinds of classes (or interfaces): // a) Top level classes // b) Nested classes (static m

時間戳隨機數的總結以及顯示年月日與時間的函式

    時間戳是指從1970年1月1日到此刻一共的時間秒數。Windows上C庫函式time(NULL),產生隨機數函式一般是利用時間戳。     但是首先應該有個概念:計算機不會產生絕對的隨機數,計算機只能產生“偽隨機數”,“偽”是有規律的意思,就是計算機產生的偽隨機數既

使用KVC進行字典模型

在專案中我們一般的都會碰到Json欄位請求回來進行模型封裝的情況,一般我們是建立一個Model然後Model裡面有Json請求回來的模型字典裡的各種欄位,類似 name,age…….之類的。封裝的時候拿到對應的模型字典,然後分別進行各個欄位的賦值,這個動作按照M

java 類方法實例方法 以及 類變量實例變量

ati 所有 ron 變量 執行 成員 退出 strong 修飾 類體中的方法分為實例方法和類方法兩種,用static修飾的是類方法 類方法: 對於類中的類方法,在該類被加載到內存時,就分配了相應的入口地址。從而類方法不僅可以被類創建的任何對象調用執行,也可以直接通過類名調

JQuery元素屬性樣式操作、以及設置元素內容

ava 例如 term wid 集合 遍歷 內容 ssd each 一、JQury元素屬性操作通過JQuery可以對元素本身的屬性進行操作,包括獲取屬性的屬性值,設置屬性的屬性值,並且可以刪除屬性值(attr()和removeAttr())。二、JQuery樣式操作元素樣式

詳談Apache、Nginxtomcat的區別以及處理靜態頁面動態頁面的方式

請求 php腳本 特點 java類 是你 源碼 proc 總結 愛好者 就目前來說,網站主要分為靜態頁面和動態頁面,純靜態頁面的網站已經比較少見了,大型網站一般使用的是靜態頁面+動態頁面的建站技術,還有一部分網站是純動態頁面。負責處理這些頁面的軟件我們通常稱之為web容器,

教你前端如何一個人從零基礎開發完整的小程式專案,包括後臺視覺化資料庫。該專案實現了個人簡歷的增刪改查以及展示轉發分享,以及收藏他人簡歷檢視,還有最近瀏覽過的簡歷

GitHub:https://github.com/susuGirl/resume 微信小程式名:你的專屬簡歷(微信可直接搜尋出來檢視),教你前端如何一個人從零基礎開發完整的小程式專案,包括後臺視覺化資料庫。該專案實現了個人簡歷的增刪改查以及展示和轉發分享,以及收藏他人簡歷和檢視,還

Spark SQL中使用StringIndexerIndexToString來對字串資訊進行索引反索引

簡介 本篇部落格使用Kaggle上的AdultBase資料集:Machine-Learning-Databases 此資料集雖然歷史比較悠久,但是資料格式比較容易處理,而且資訊比較全面,適合資料處理入門。 本篇部落格使用了Spark SQL的相關語句,實現了以下

關於js中的作用域作用域鏈以及常見的問題結果方法

<script type="text/javascript"> var num=1; function fun(){ var num=2; function fun1(){ var num=3; console.log(num); } functi

divspan的區別以及行內元素塊元素的轉換

div和span的區別以及行元素和塊元素的轉換?相同點:div和span都可以將HTML元素組合起來,類似一個盒子將裡面的內容當作一個整體來處理,從而實現整體作用效果,提高效率。不同點:div是塊級元素,是可用於組合其他HTML元素的容器,其常用的用途是文件佈局,主要用於頁面

抽象類介面的區別 以及選擇抽象類介面的應用場景

介面和抽象類有什麼區別 你選擇使用介面和抽象類的依據是什麼? 介面和抽象類的概念不一樣。介面是對動作的抽象,抽象類是對根源的抽象。 抽象類表示的是,這個物件是什麼。介面表示的是,這個物件能做什麼。比如,男人,女人,這兩個類(如果是類的話……),他們的抽象類是人。說

Python同時安裝py2.xpy3.x,以及Windows下virtualenvflask的安裝

1.py2.x和py3.x的安裝 由於學習需要或者個人折騰,可能會在同一臺電腦上面安裝py2.x和py3.x兩個版本。下面就開始介紹如何安裝,還有pip的使用。 1.安裝好py2.x和py3.x到本機,並配置好環境變數,關於環境變數,可以在安裝時選擇add

swift4.0 YYModel進行陣列轉模型時, 轉換的資料為nil

在進行陣列轉模型的操作時,資料轉化後為空, 換成使用oc建立的模型類之後,可以進行互轉, Swift 4 裡面繼承NSObject 不再預設在變數前 新增@objc; YYModelMeta中的_keyMappedCount獲取不到不帶@objc的變數,所以_keyMappedCount一直

關於執行時異常(Runtime Exception)受檢查的異常(Checked Exception)以及系統異常普通異常的一些總結

Exception 表示程式還能夠克服和恢復的問題,Exception 類又分為執行時異常(Runtime Exception)和受檢查的異常(Checked Exception),所謂執行時異常就是開發人員編寫程式碼時不會報紅,但是執行不得當的話會執行出錯,也

Redis的安裝以及在專案中使用Redis的一些總結體會

第一部分:為什麼我的專案中要使用Redis 我知道有些地方沒說到位,希望大神們提出來,我會吸取教訓,大家共同進步! 註冊時郵件啟用的部分使用Redis 傳送郵件時使用Redis的訊息佇列,減輕網站壓力。 使用Lucene.Net在進行分詞時使用Redis訊息佇列和多執行緒來避免介面卡死等效能問

MySql資料庫在表中新增新欄位,設定主鍵,設定外來鍵,欄位移動位置,以及修改資料庫後如何進行部署維護的總結

1,為當前已有的表新增新的欄位 alter table student add studentName varchar(20) not null; 2,為當前已有的表中的欄位設定為主鍵自增 alter table student add constraint PK_studentId primaryKe

蜜罐技術——通過布置一些作為誘餌的主機、網絡服務或者信息,誘使攻擊方對它們實施攻擊,從而可以對攻擊行為進行捕獲分析

技術 使用 alt name 防火墻 text 來源 情報 優點 蜜罐技術本質上是一種對攻擊方進行欺騙的技術,通過布置一些作為誘餌的主機、網絡服務或者信息,誘使攻擊方對它們實施攻擊,從而可以對攻擊行為進行捕獲和分析,了解攻擊方所使用的工具與方法,推測攻擊意圖和動機,能夠讓防