OC中鍵值程式設計(KVC)的實現

2021-06-10 21:43:12 字數 4049 閱讀 2020

key-value coding(kvc)是用來使得乙個類的行為擺脫它需要依附執行的特定屬性的一種方式。它通常與nskeyvaluecoding協議聯絡在一起當然也有一系列其他的方法來實現相同的效果。在這篇文章中,我關注為什麼kvc是重要的而且要介紹5種不同的方式來實現這個功能。介紹

nskeyvaluecoding協議自從mac os x10.0起就已經在cocoa中,但是它給人留下深刻印象是在mac os x10.3中當使用者介面繫結展示了他們的潛力時——允許使用者介面通過配置資料而不用更改**就可以控制連線到物件的屬性。

kvc的核心概念存在於大多數的程式設計框架中,它是流行而且普遍的在cocoa中,當然也在其他的編譯程式框架中。

什麼是key-value coding?

kvc的思想是相當簡單的,不用直接獲取或設定乙個物件的屬性,kvc通過傳遞乙個」key」(通常是乙個字串)來獲取或更改與這個」key」相關的屬性。這個聽起來非常像nsdictionary

例如:

123

45

// set a property directly...

someobject.someproperty = somevalue;

// ...or set the same property using key-value coding

[someobject setvalue:somevalue forkey:

@"someproperty"

];

為什麼你要這樣做?答案是它簡化了設定某個屬性值的行為。

設想有這樣乙個可以編輯姓名和位址的**:

沒有kvc方式,利用nstableviewdatasource方法來編輯某一行也許要這樣:

123

4567

891011

1213

14

-

(void

)tableview:

(nstableview

*)atableview

setobjectvalue:

(nsstring

*)anobject

fortablecolumn:

(nstablecolumn

*)atablecolumn

row:

(int

)rowindex

elseif(

[[atablecolumn identifier] isequal:

@"address"])

}

而利用kvc方式,這個方法變成:

123

4567

-

(void

)tableview:

(nstableview

*)atableview

setobjectvalue:

(nsstring

*)anobject

fortablecolumn:

(nstablecolumn

*)atablecolumn

row:

(int

)rowindex

前面我提到了繫結(bindings):這個方法並沒有使用使用者介面繫結。但這也確實展示了乙個簡化的實現繫結的方式。

這個kvc方法是更好的因為它不必編輯每乙個分立的屬性。這就是kvc的精華之所在。

當資料量增加時,kvc愈發體現它的高效。乙個有1000列的**其實只需要與上述相同量的**就可以實現編輯。

kvc方法1:nskeyvaluecoding protocol

我目前展示的所有kvc方式都是利用nskeyvaluecoding協議。其實,我稱它為協議是因為它確實是乙個通俗的協議(nsobject中乙個分類)。

這個分類繼承setvalue:forkey: 和valueforkey:兩個方法使你可以設定和獲取值通過nsstring的keys。

優點:

缺點:繼承的搜尋路徑使這種方法是最慢的kvc方法(可以閱讀我前面相關的文章replacing core data key paths)。

要求這個類中有個相關方法或者有變數與這個名字的屬性相關,而且可以被nskeyvaluecoding找到。

僅僅支援nsstrings作為屬性的「key」。

kvc 方法2: 手動設定nskeyvaluecoding 行為的子集

nskeyvaluecoding根據選擇器來查詢方法,根據名字查詢成員。

這些工作需要你首先進行設定。

123456

// manual kvc setter method implementation

nsstring

*setterstring =[@

[somekeystring capitalizedstring]

];[someobject performselector:nsselectorfromstring(setterstring) withobject:somevalue];

// manual kvc ivar setter

object_setinstancevariable(someobject, somekeystring, somevalue);

為什麼你要這樣做而不是使用nskeyvaluecoding方法呢?當你要避免使用nskeyvaluecoding預設找到的方法或成員時你可以使用這個方法。這個方法允許你自定義查詢路徑。

優點:

缺點:

kvc 方法3: 關聯物件

objective-c 2.0執行時(在iphone或64位mac os x程式上)允許設定乙個物件關聯到任何其他物件。這使得執行時任何物件都可以通過key來任意被設定額外的屬性,而不需要來自這個物件的方法或成員支援。

objc_setassociatedobject(someobject, somekey, somevalue, objc_association_retain_nonatomic);
你會用到這個方法的主要原因是你打算在外部設定物件的屬性—例如,不用物件支援,被包含於甚至不知道這個屬性的路徑。某個屬性可以被程式的其它部分根據需要來設定到乙個物件上面。

優點:

缺點:kvc 方法 4: 將選擇器作為keys

kvc根本上來說是通過key來查詢乙個屬性,之後在這個屬性上進行操作。

objective-c在它的核心有乙個檢查—方法查詢。這個查詢的keys就是選擇器。

objc_msgsend(someobject, somesetterselector, somevalue);
這個方法與手動設定nskeyvaluecoding方法部分類似,但是它不是形成乙個選擇器的字串來作為key,這個方法直接利用選擇器作為key。

這個方法的缺點是需要為獲取和設定分別設定選擇器。

優點:

缺點:

kvc 方法5: 自己實現它

最後乙個方法是自己處理這個實現。如果你需要最大的靈活性的話(處理特殊的keys或者資料)或者想要暴露乙個物件實體的不同的關鍵值。

最簡單的實現這一條的方式是暴露獲取和設定方法,之後在物件包含的dictionary上獲取和設定這些值。

123

4567

89

-

(void

)setcollectionvalue:(id

)value forkey:

(nsstring

*)key-(

id)getcollectionvalueforkey:(

nsstring

*)key

你可以使用cocoa中任何一種關鍵值儲存結構來處理這些值內部儲存:

或者你自己的儲存方案。

優點:

缺點:結論

使用key-value coding並不是必需的。實現整個工程不用kvc當然是可能的。但是,它是最好的**樣式之一,可以減少重複**以及使得類可以復用。

你可以看到,有許多不同的kvc程式設計方法。nskeyvaluecoding可能是最靈活的,復用的而且能夠很好的被cocoa支援的方式,因此除非你需要上面提到的其他方法的優點之一或者你打算使你的方案限定解決特定的問題,這個方法可能是最好的方式。

鍵值編碼 KVC 簡單的KVC

main.m kvc一 created by goddog on 15 1 3.1.我們可以通過setter和getter方法來設定和修改物件的屬性,同時也可以通過鍵值編碼 kvc 來操作物件屬性。2.何為kvc 以字串的形式間接的操作物件的屬性。設定值用 setvalue 屬性值 forkey 屬...

OC8 屬性 KVC是鍵值編碼

1.屬性,是oc提供的一種快速的模式化的建立例項變數的方式。1 屬性是通過 property標記的,2 屬性會在背後,默默的幫我們做set和get方法 2.屬性做的工作 1 建立乙個例項變數,名字是下劃線加屬性名,2 幫我們自動get和setter 的方式,建立一組方法,3.點語法,點語法是專門為了...

OC語言基礎十三 JSON資料,KVC鍵值編碼

kvc鍵值編碼 網路資料傳輸中,有2種資料格式最常用。json和xml資料。json資料的資料結構簡單,冗餘資料少,網路資料傳輸的時候json資料比xml資料的傳輸快。但是json資料的結構相對簡單,相比於xml來講可讀性要差一些。的是字典,的是陣列 將上面幾種,表示成清晰可見的格式。字串要用引號來...