整理了一下關於KVO的姿勢

2021-09-08 04:28:25 字數 3654 閱讀 3135

1)

+ (bool)automaticallynotifiesobserversforkey:(nsstring *)thekey

是為了防止系統重複實現;

2)willchangevalueforkey:didchangevalueforkey:呼叫時都會呼叫valueforkey:,並把得到的結果分別當成old value和new value,以告知觀察者。

3)valueforkey只在觀察者關心時呼叫。

kvo(key-value observing)提供了一種機制,當某個物件的某個特定的property被改動時,它能夠允許別的物件接到這個通知。

實現kvo的前提條件就是,這個類和它的這個property是kvc compliant的。對於這個類來說,valueforkey:setvalue:forkey:這兩個方法被合理的實現(nsobject對這兩個方法有了預設的實現);如果這個property是乙個attribute或者to-one relationship的話,要滿足以下幾個條件的至少乙個(其中,key表示這個property對應的key):

這個類以key為名,宣告了乙個property;

這個類實現了以key為名的accessor方法;

這個類以key或者_key為名,宣告了乙個例項變數。

對乙個property設定乙個觀察者需要這樣幾個步驟:

一. 使用addobserver:forkeypath:options:context:方法,對需要觀察的property註冊乙個觀察者

這時,觀察者物件和被觀察的物件之間會建立聯絡,這種聯絡是針對於物件的,而不是針對於類的。

其中可以指定options引數:

可以指定多個nskeyvalueobservingoptions,將他們用「或」連線後,作為options引數。

可以將任意物件作為context引數,它會和觀察者實現的observevalueforkeypath:ofobject:change:context:方法中的context引數指向同乙個物件。

二. 觀察者必須實現observevalueforkeypath:ofobject:change:context:方法,並定義觀察者應該如何響應change notification

三. 當被觀察的property的值發生變化的時候,或者它依賴的某乙個key的值發生變化的時候,observevalueforkeypath:ofobject:change:context:方法會自動被呼叫

這裡的改變被觀察的property的值,指的應該是這樣幾種方式中的一種:

呼叫key-value compliant的accessor方法;

使用key-value coding方法,如setvalue:forkey:insertvalue:inpropertywithkey:

使用mutablearrayvalueforkey:取得乙個**物件,並操作這個**物件。

所以如果僅僅是改變了某個property所生成的instance variable的值,自動的change notification是不會傳送的。

四. 當不再需要這個觀察者的時候,需要呼叫removeobserver:forkeypath:或者removeobserver:forkeypath:context:方法,移除這個觀察者

應該盡量使用removeobserver:forkeypath:context:方法,因為如果當同樣的observer和同樣的key path被多次註冊,但是每次註冊使用的是不同的context,這時如果使用removeobserver:forkeypath:方法,它就需要猜測到底移除哪乙個觀察者,當然這很可能猜錯。

那些在addobserver:forkeypath:options:context:中指定的物件,必須在deallocate之前被移除掉。

按照上面說的方法,為某個property設立乙個觀察者,這個觀察者就會收到系統自動傳送的change notification。然而,第三方程式設計師也可以手動傳送change notification。手動傳送change notification可以更自由的控制通知傳送的邏輯。

如果乙個類想要實現手動的change notification傳送,則必須重寫nsobject實現的automaticallynotifiesobserversforkey:方法,並對需要實現手動傳送的key返回no,其餘則呼叫super。

官方示例**:

+ (bool)automaticallynotifiesobserversforkey:(nsstring *)thekey  else  return automatic; }

然後在property的值改變之前呼叫willchangevalueforkey:,在值改變之後呼叫didchangevalueforkey:。當然,在什麼樣的情況下才呼叫這兩個方法,是由第三方程式的邏輯決定的。

如果乙個操作造成了多個key的值的改變,則willchangevalueforkey:didchangevalueforkey:必須巢狀著呼叫。

官方示例**:

- (void)setopeningbalance:(double)thebalance 

willchangevalueforkey:didchangevalueforkey:呼叫時都會呼叫valueforkey:,並把得到的結果分別當成old value和new value,以告知觀察者。

做了個小實驗,發現在自動傳送change notification的情況下,willchangevalueforkey:didchangevalueforkey:也會被呼叫,看來系統也是通過這兩個方法來傳送通知的。

如果手動傳送change notification的property是ordered to-many relationship,則不僅要指定被改變的key,還要指定改變的型別和index。型別用nskeyvaluechange來表示。

對於to-one relationship的property,重寫keypathsforvaluesaffectin**alueforkey:或者keypathsforvaluesaffecting方法可以定義這個key所依賴的一系列key。但是這個方法僅限於to-one relationship的property。

官方示例**:

+ (nsset *)keypathsforvaluesaffectingfullname 

而對於to-many relationship,要麼手動觀察每乙個依賴的key,要麼利用core data來完成這個任務。

整理了一下 發個關於埠的

關於埠的有 可能不全 系統服務及木馬預設埠表 win2k server ip策略拒絕多餘埠教程 原創 埠對映是什麼意思?windwos2000server埠對映是這樣做 如何關閉埠?怎樣知道對方的1080埠是否開了?堵住黑客常用的缺口 從禁止埠入手 使用ipsec阻止對tcp135埠的訪問 怎樣封堵...

整理了一下買的電腦書,整理了一下學習思路

這幾天,整理了整理以前買的電腦技術書籍,發現有不少書還沒有看過,挑了一本 程式設計師修練之道 先看著,這本書兩年多前就買了,以前在學校裡的時候看了大概四分之一,記得看到這部分的時候覺得內容於實際不太搞界,看起來比較吃力,所以就擱下了。一直沒看,這幾天終於把全本書看完了。由於自已現在從事軟體開發,所以...

整理了一下自己的空間

明天就開始放五一大假 上班不想做工作相關的東西,但沒辦法,還是得做個樣子 有點不厚道吧 偷偷上來看我的blog,已經落了乙個月沒有寫東西!同時在網上轉悠,看到了乙個他自已建的blog站點。看的很勤快,雖然有些篇幅寫的不是很長,但卻真實記錄著他的生活和工作,記錄著他的成長和思想。尤其喜歡他logo上的...