深入理解 KVC\KVO 實現機制 — KVC

KVC和KVO都屬于鍵值編程而且底層實現機制都是isa-swizzing,所以本來想放在一起講的。但是篇幅有限所以就分成了兩篇博文?KVO實現機制傳送門

KVC概述

  • KVC是Key Value Coding的簡稱。它是一種可以通過字符串的名字(key)來訪問類屬性的機制。而不是通過調用Setter、Getter方法訪問。
  • 關鍵方法定義在 NSKeyValueCodingProtocol
  • KVC支持類對象和內建基本數據類型。

KVC使用

  • 獲取值
    valueForKey: 傳入NSString屬性的名字。
    valueForKeyPath: 屬性的路徑,xx.xx
    valueForUndefinedKey 默認實現是拋出異常,可重寫這個函數做錯誤處理

  • 修改值
    setValue:forKey:
    setValue:forKeyPath:
    setValue:forUnderfinedKey:
    setNilValueForKey: 對非類對象屬性設置nil時調用,默認拋出異常。

KVC鍵值查找

搜索單值成員
  • setValue:forKey:搜索方式

    1、首先搜索setKey:方法。(key指成員變量名,首字母大寫)

    2、上面的setter方法沒找到,如果類方法accessInstanceVariablesDirectly返回YES。那么按 _key,_isKey,key,iskey的順序搜索成員名。(NSKeyValueCodingCatogery中實現的類方法,默認實現為返回YES)

    3、如果沒有找到成員變量,調用setValue:forUnderfinedKey:

  • valueForKey:的搜索方式

    1、首先按getKey,key,isKey的順序查找getter方法,找到直接調用。如果是BOOL、int等內建值類型,會做NSNumber的轉換。

    2、上面的getter沒找到,查找countOfKey、objectInKeyAtindex、KeyAtindexes格式的方法。如果countOfKey和另外兩個方法中的一個找到,那么就會返回一個可以響應NSArray所有方法的代理集合的NSArray消息方法。

    3、還沒找到,查找countOfKey、enumeratorOfKey、memberOfKey格式的方法。如果這三個方法都找到,那么就返回一個可以響應NSSet所有方法的代理集合。
    4、還是沒找到,如果類方法accessInstanceVariablesDirectly返回YES。那么按 _key,_isKey,key,iskey的順序搜索成員名。

    5、再沒找到,調用valueForUndefinedKey。

KVC實現分析

KVC運用了isa-swizzing技術。isa-swizzing就是類型混合指針機制。KVC通過isa-swizzing實現其內部查找定位。isa指針(is kind of 的意思)指向維護分發表的對象的類,該分發表實際上包含了指向實現類中的方法的指針和其他數據。

比如說如下的一行KVC代碼:

[site setValue:@"sitename" forKey:@"name"];//會被編譯器處理成SEL sel = sel_get_uid(setValue:forKey); IMP method = objc_msg_loopup(site->isa,sel); method(site,sel,@"sitename",@"name");

每個類都有一張方法表,是一個hash表,值是還書指針IMP,SEL的名稱就是查表時所用的鍵。
SEL數據類型:查找方法表時所用的鍵。定義成char*,實質上可以理解成int值。
IMP數據類型:他其實就是一個編譯器內部實現時候的函數指針。當Objective-C編譯器去處理實現一個方法的時候,就會指向一個IMP對象,這個對象是C語言表述的類型。

KVC的內部機制:
一個對象在調用setValue的時候進行了如下操作:

  • (1)根據方法名找到運行方法的時候需要的環境參數
  • (2)他會從自己的isa指針結合環境參數,找到具體的方法實現接口。
  • (3)再直接查找得來的具體的實現方法

轉載于:https://www.cnblogs.com/Ghosgt/p/5973085.html

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

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

相關文章

python中字典和集合對象是無序的_Python基礎(四):元組、字典和集合

基礎學習第四彈,常用對象:元組、字典和集合一、元組1.1 元組的應用場景思考:如果想要存儲多個數據,但是這些數據是不能修改的數據,怎么做?答:列表?列表可以一次性存儲多個數據&#…

Windows常用必備軟件整理,太全了,值得收藏

目錄 1、Office系列 2、殺毒軟件 3、視頻播放和視頻處理 4、音樂播放 5、壓縮解壓 6、輸入法 7、PDF閱讀軟件 8、文件加密 9、網盤 10、社交聊天 11、日常辦公軟件 ?12、圖片/照片處理? 13、系統自帶的工具 Windows常用必備軟件整理,太全了,值得收藏&…

常見的 Error 和 Exception

如下是常見的 Error 和 Exception: 1)運行時異常(RuntimeException)也稱 【非檢查型異常 UncheckedException】: Nullpointer Exception:空指針異常;ClassCastException:類型強制轉…

Datatable/Dataset 轉 JSON方法

當數據庫表的數據在一般處理程序中查出來需要將這個表數據返回到前臺的jquery中,需要將數據拼成json字符串形式,這里是將數據庫數據查出放在Datatable中,然后在一般處理程序中將datatable轉成json的幾個方法,根據不同的情況調用不…

數據庫:SQLServer數據庫備份方式介紹

今天小編給大家梳理一下數據庫備份的相關知識,希望對大家能有所幫助!1、完整備份完整備份相當于針對整個數據庫備份,包含數據庫的全部內容。數據庫完整備份可以將數據庫的所有內容備份為一個.Bak文件。后續可以通過該備份文件在本機或者拷貝到…

注入雙括號報錯注入_SQL手動注入:sqlilabs(less110)

種一棵樹最好的時間是10年前,其次是現在。忘了是誰前言說實話,由于前段時間學 python ,對于 OWASP TOP10 漏洞的學習都有所落下,雖然現在也在慢慢復習當中,但是今晚談及的 SQL 注入漏洞手動注入和自動化(sqlmap)注入的…

try、catch、finally用法總結

一、異常的處理:抓拋模型過程一:"拋":程序在正常執行的過程中,一旦出現異常,就會在異常代碼處生成一個對應異常類的對象。并將此對象拋出。一旦拋出對象以后,其后的代碼就不再執行。關于異常對象…

markdown學習/mou

markdown編輯器mou markdown編輯器的使用很簡單,mac平臺選擇課 MOU 這款比較輕的客戶端。 使用也很方便,打開軟件,->helo->mou help 就有各種示例,照葫蘆畫瓢。 有些關鍵字需要轉義,使用的時候要注意,比如插入一…

硬件知識:內存條出現故障的解決方案!

“電腦不時的突然出現藍屏”,“開機之后毫無規律的死機”,“開不了機,一開機就出現嘶鳴聲”,如果你的電腦出現了以上情況,就是你的內存兼容性出了問題,那么這種故障該如何解決呢?下面&#xff0…

api zabbix 拓撲圖 獲取_zabbix網絡拓撲圖配置-Maps(示例代碼)

zabbix network map”可以簡單的理解為動態網絡拓撲圖,可以針對業務來配置zabbix map,通過map可以了解應用的整體狀況:服務器是否異常、網絡是否有故障、應用當前什么狀態。如果你不需要這些東西,至少你可以通過network map繪制一…

.NET 面試題(2)

61、Application 、Cookie和 Session 兩種會話有什么不同? 1.Application 儲存在服務端,沒有時間限制,服務器關閉即銷毀(前提是自己沒寫銷毀方法) 2.Session 儲存在服務端,客戶端(瀏覽器&#x…

盤點程序員必備的專業術語,值得看一看

英文縮寫 API 應用程序接口(英語:Application Programming Interface,簡稱:API),又稱為應用編程接口,就是軟件系統不同組成部分銜接的約定。由于近年來軟件的規模日益龐大,常常需要把…

app上線發布流程_APP上線發布流程

上線流程上線流程的主要步驟在上線之前對程序進行內存動態和靜態分析,注意啟動圖的屏幕適配,不然會自動拉升屏幕,使得屏幕自動適配失效生成cer證書:cer是一個跟電腦相關聯的證書文件,讓電腦具備真機調試的功能要借助CS…

java.io.IOException: Broken pipe 的異常處理

斷開的管道 java.io.IOException: Broken pipe 解決方法 一、Broken pipe產生原因分析 1.當訪問某個服務突然服務器掛了,就會產生Broken pipe; 2.客戶端讀取超時關閉了連接,這時服務器往客戶端再寫數據就發生了broken pipe異常! 二、方案…

IDEA中安裝配置Jrebel熱部署插件用法筆記

今天給大家介紹一下IDEA中安裝配置Jrebel熱部署插件用法,希望對大家能有所幫助!1、Jrebel插件介紹JRebel屬于一款JAVA虛擬機插件,它可以讓你的項目在不需要進行重新編譯的情況下,就可以實時看到代碼的變化對項目的影響。這對我們開…

集成支付寶錢包支付iOS SDK的方法與經驗

下載 首先,你要想找到這個SDK,都得費點功夫。現在的SDK改名叫移動支付集成開發包了。 https://b.alipay.com/order/productDetail.htm?productId2013080604609654&tabId4#ps-tabinfo-hash Baidu和Googlep排在前面的支付寶開放平臺,里面的…

zabbix 監控項自動發現過濾_【Zabbix監控教程】LLD低級別自動發現配置教程

低級別自動發現簡稱LLD,使用低級別自動發現可以實現根據Agent的實際情況去自動創建監控項,適用于配置不一的環境。比如A主機有3塊硬盤,B主機有5塊硬盤,如果不使用LLD的話就需要人肉去為每個硬盤創建監控項。而有了LLD就可以實現自…

Spring Boot單元測試報錯java.lang.IllegalStateException: Could not load TestContextBootstrapper [null]

一:運行test類方法時候報錯 報錯 java.lang.IllegalStateException: Could not load TestContextBootstrapper [null]. Specify BootstrapWiths value attribute or make the default bootstrapper class available.at org.springframework.test.context.BootstrapU…

PHP底層原理分析和底層擴展編寫

運行原理 http://www.phpchina.com/article-40203-1.htmlPHP底層開發 可以理解為就是C的開發,那么簡單地說如果我們要查看某個PHP函數的底層實現怎么看呢?需要PHP源碼包:http://www.php.net/downloads.php主要目錄是Zend 和ext(寫擴展的目錄…

硬件知識:DP接口和HDMI接口對比,看完你就懂了

目錄 一、DP接口 二、HDMI接口 三、總結 電腦顯示器高清傳輸通過會用到兩個接口,就是DP接口和HDMI接口,今天電腦學習小編帶大家對比一下這兩個接口。 一、DP接口 DisplayPort縮寫DP,是一個由PC及芯片制造商聯盟開發,視頻電子標準協…