KVC/KVO 本質

KVO 的實現原理

  1. KVO是關于runtime機制實現的

  2. 當某個類的對象屬性第一次被觀察時,系統就會在運行期動態地創建該類的一個派生類,在這個派生類中重寫基類中任何被觀察屬性的setter方法。派生類在被重寫的setter方法內實現真正的通知機制

  3. 如果原類為Person,那么生成的派生類名為NSKVONotifying_Person

  4. 每個類對象中都有一個isa指針指向當前類,當一個類對象的第一次被觀察,那么系統就會偷偷講isa指針指向動態生成的派生類,從而在給被監控屬性復制是執行的是派生類的setter方法

  5. 鍵值觀察通知依賴于NSObject的兩個方法:willChangeValueForKey:和didChangeValueForKey:,在一個被觀察屬性發生改變之前,willChangeValueForkey:和didChangeValueForKey:;在一個被觀察屬性發生改變之前,willChangeValueForKey:一定會被調用,這就會記錄舊的值。而當改變發生后,didChangeValueForKey:會被調用,繼而observeValueForKey:ofObject:change:context:也會被調用

舉例偽代碼_NSSet*ValueAndNotify

- (void)setAge:(int)age
{_NSSetIntValueAndNotify();
}// 偽代碼
void _NSSetIntValueAndNotify()
{[self willChangeValueForKey:@"age"];[super setAge:age];[self didChangeValueForKey:@"age"];
}- (void)didChangeValueForKey:(NSString *)key
{// 通知監聽器,某某屬性值發生了改變[oberser observeValueForKeyPath:key ofObject:self change:nil context:nil];
}

720299-20190108131406313-1322703237.png

KVC的實現原理

  • KVC是Key Value Coding的簡稱。它是一種可以通過字符串的名字(key)來訪問類屬性的機制。而不是通過調用Setter、Getter方法訪問。KVC的方法定義在Foundation/NSKeyValueCoding中。

KVC使用的基本方法:

- (void)setValue:(nullableid)value forKey:(NSString*)key;//通過Key來設值
- (void)setValue:(nullableid)value forKeyPath:(NSString*)keyPath;//通過KeyPath來設值
- (nullableid)valueForKey:(NSString*)key;//直接通過Key來取值
- (nullableid)valueForKeyPath:(NSString*)keyPath;//通過KeyPath來取值

KVC 賦值 setValue:forKey:

  1. setValue:forKey:將鍵字符串key所對應的屬性的值設置為value。(按照setKey:、_setKey:順序查找方法)如果沒有找到Set方法的話,將調用方法setValue:ForUndefinedKey:。并拋出異常 NSUnknowKeyException

2.?若沒有找到Set方法,會調用對象的類方法+ (BOOL)accessInstanceVariablesDirectly;此方法返回YES時(默認返回YES),會按照_key,_iskey,key,iskey的順序搜索成員,然后賦值。

3.? 若都沒找到成員變量,將調用方法setValue:ForUndefinedKey:。并拋出異常 NSUnknowKeyException

KVC 取值值 valueForKey:

  1. 按先后順序搜索getKey:、key、isKey、三個方法,若某一個方法被實現,取到的即是方法返回的值,后面的方法不再運行。如果是BOOL或者Int等值類型, 會將其包裝成一個NSNumber對象。

  2. 若這三個方法都沒有找到,則會調用+ (BOOL)accessInstanceVariablesDirectly方法判斷是否允許取成員變量的值。若返回NO,直接調用- (nullable id)valueForUndefinedKey:(NSString *)key方法,并拋出異常 NSUnknowKeyException

  3. 若返回YES,會按先后順序取_key、_isKey、 key、isKey成員變量的值。調用- (nullable id)valueForUndefinedKey:(NSString *)key方法。

補充

  1. KVC提供屬性值正確性驗證的API,它可以用來檢查set的值是否正確、為不正確的值做一個替換值或者拒絕設置新值并返回錯誤原因。
- - (BOOL)validateValue:(inout id __nullable * __nonnull)ioValue forKey:(NSString *)inKey error:(out NSError **)outError;
  1. KVC中的異常.獲取值時找不到key- (nullable id)valueForUndefinedKey:(NSString *)key;

  2. 設值時找不到key- (void)setValue:(nullable id)value forUndefinedKey:(NSString *)key;

  3. 給不能設置nil的屬性設置了nil。
  • 如果你在SetValue方法時面給Value傳nil,則會調用這個方法
  • (void)setNilValueForKey:(NSString *)key;

轉載于:https://www.cnblogs.com/ShaoYinling/p/10238492.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/248683.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/248683.shtml
英文地址,請注明出處:http://en.pswp.cn/news/248683.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

mysql 各個版本驅動jar包

http://central.maven.org/maven2/mysql/mysql-connector-java/轉載于:https://www.cnblogs.com/mzdljgz/p/11063354.html

攻破 程序員35歲 “瓶頸” 那都不是事!

我正在參與CSDN《新程序員》有獎征文,點擊和我一起參與吧 下面呢,我就在這里給大家講述一下我的經歷吧。 初衷 作為程序猿的我們,初衷在哪里,高薪?體面?熱愛?曾經有一個同學聊天中說到這個話…

Dollar Dayz POJ - 3181

解法 完全背包大數。。。不想寫大數了放個python得了 代碼 dp[0 for i in range(2000)] n,kmap(int,input().split()) num[i for i in range(1,k1)] dp[0]1 for i in range(k):for j in range(num[i],n1):dp[j]dp[j-num[i]] print(dp[n]) 轉載于:https://www.cnblogs.com/bacca…

Vue項目中引用‘阿里巴巴字體圖標庫iconfont’

1.前言 在實際開發中,作為前端開發人員的我們經常會遇到下面這種ui圖 我們看到在上面兩個平臺設計圖中的出現了大量的圖標,在某種情況下,這種圖標是需要我們自己去找的,不要噴我們的 ui 哈,主要是我喜歡麻煩 哈哈&…

學習進度條-17

第十七周 所花時間(包括上課) 5小時 代碼量(行) 300 博客量(篇) 4 了解到的知識點 對sql server數據庫的連接,頁面的跳轉 轉載于:https://www.cnblogs.com/zhaoxinhui/p/11068736.html

項目流程

轉載于:https://www.cnblogs.com/Koma-vv/p/10243286.html

最詳細的講解 JS 原型與原型鏈

文章目錄一. 普通對象與函數對象二. 構造函數三. 原型對象四. proto五. 構造器六. 原型鏈七. Prototype總結一. 普通對象與函數對象 JavaScript 中,萬物皆對象!但對象也是有區別的。分為普通對象和函數對象,Object 、Function 是 JS 自帶的函…

jmeter分布式壓測原理簡介1

1、什么叫分布式壓測? 分布式壓測:模擬多臺機器向目標機器產生壓力,模擬幾萬用戶并發訪問 2、分布式壓測原理:如下 3、更多補充.....待添加 轉載于:https://www.cnblogs.com/yoyoblogs/p/11071774.html

十三 re模塊

一:什么是正則? 正則就是用一些具有特殊含義的符號組合到一起(稱為正則表達式)來描述字符或者字符串的方法。或者說:正則就是用來描述一類事物的規則。(在Python中)它內嵌在Python中&#xff0c…

帶你玩轉 ui 框架 ——scoped及樣式穿透問題詳解

前言 在我們前端的開發中經常會使用到各種 ui 框架 下面這兩個是比較火的,也是我常用的兩個ui框架。 問題描述 但是在使用框架的時候難免會遇到需要改變組件中的一些樣式,當然如果我們所有頁面的組件樣式都是統一的話,我們可以進行全局設置…

Npoi Web 項目中(XSSFWorkbook) 導出出現無法訪問已關閉的流

NPOI生產.xlsx文件件時,在使用book.Write(ms);后,會關閉流,這樣導致再次使用Respons輸出流的時候就出錯了。 造成關閉流的主要原因有時其實是跨域,同域是沒有問題的。 //新建類 重寫Npoi流方法 public class NpoiMemoryStream : M…

三分鐘帶你掌握 CSS3 的新屬性

文章目錄1. css3簡介2. css3邊框2.1 邊框圓角2.2 邊框陰影3. css3背景3.1背景圖大小3.2背景圖起始點4. css3文本效果4.1 文本陰影4.2 文本換行5. css3字體圖標6. css32D轉換7. css3 3D轉換8. css3 transition8.1 單項改變8.2 單項改多項改變9. css3 動畫1. css3簡介 CSS 用于控…

用 div 仿寫 input 和 textarea 功能

div仿寫input和textarea input不能換行&#xff0c;textarea也不能跟隨內容多少而增加高度。 contenteditable true; <div class"msg_content" contenteditable"true" placeholder在這里輸入您的留言或建議></div> .msg_content {box-sizing:…

Vue項目中如何設置動態的TDK

TDK是什么 TDK就是網站的標題&#xff08;title&#xff09;、描述&#xff08;description&#xff09;和關鍵詞&#xff08;keyword&#xff09; TDK在哪里 上面大佬對TDK的概念解釋的很全面&#xff0c;但是在網頁中的TDK在哪里呢&#xff0c;作為開發人員打開F12我們就…

[Pytorch]Pytorch的tensor變量類型轉換

原文&#xff1a;https://blog.csdn.net/hustchenze/article/details/79154139 Pytorch的數據類型為各式各樣的Tensor,Tensor可以理解為高維矩陣。與Numpy中的Array類似。Pytorch中的tensor又包括CPU上的數據類型和GPU上的數據類型&#xff0c;一般GPU上的Tensor是CPU上的Tenso…

PHP從零開始--基礎篇

一、 變量 1.1概念 變量是存儲數據的用的容器。 1.2定義變量 變量名的語法規則&#xff1a; 可以是數字、字母、下劃線&#xff0c;但是不能以數字開頭不能出現空格變量名是區分大小寫變量名不能是系統中的關鍵字行業約定的語法規范 駝峰命名法 比如 myname 定義成 myNam…

node

? Table of Contents 1. 全局對象2. 代碼執行優先級3. 模塊導入4. 模塊加載 4.1. 文件模塊優先級4.2. 文件夾加載優先級 4.2.1. 包&#xff08;文件夾&#xff09;下的入口文件優先級4.2.2. 包加載優先級5. 核心模塊的簡單使用 5.1. events1 全局對象 globalconsole.log(globa…

一個關于WCF調用遠程鏈接返回405錯誤不允許使用此方法的問題

最近在調試WCF的接口時一直返回“405不允許使用此方法”&#xff0c;這個問題困擾了大半天&#xff0c;網上查了各種辦法&#xff0c;但是每個人遇到的問題不同還是不能解決。 最后無意之中發現問題所在&#xff0c;記錄一下幫助后面的同學解決問題。 WCF遠程方法會配置屬性Web…

PHP從零開始--循環數組

一、循環 1.1單層for循環 1.1.1基礎語法 for(初識變量;結束范圍;累加/累減){ 重復執行的代碼 } 1、 先初識化變量$i 2、 $i<100表達式進行判斷 3、 跳入循環&#xff0c;執行重復代碼 4、 累加或者累加 5、 再進行$i<100表達式判斷 6、 再跳入循環&#xff0c;執行重復…

Spring Cloud(F版)搭建高可用服務注冊中心

上一篇文章【Spring Cloud搭建注冊中心】成功搭建了一個Eureka Server服務注冊中心&#xff0c;不過相信細心的朋友都會發現&#xff0c;這個服務注冊中心是一個單節點服務注冊中心&#xff0c;萬一發生故障或者服務器宕機&#xff0c;那所有的服務可就不能使用了&#xff0c;這…