天天看點

obj-c程式設計15[Cocoa執行個體02]:KVC和KVO的實際運用

    我們在第16和第17篇中分别介紹了obj-c的kvc與kvo特性,當時舉的例子比較fun,太抽象,貌似和實際不沾邊哦。那麼下面我們就用一個實際中的例子來看看kvc與kvo是如何運用的吧。

    該例中用到了3種新的控件類型:nstableview、nsslider以及簡單的nstextfield類型。按說不能再在random類裡添加不沾邊的新增功能了,但是為了簡單,我還是把所有東西都放在random類裡喽。程式運作時界面如下:

obj-c程式設計15[Cocoa執行個體02]:KVC和KVO的實際運用

大家可以看到左上角的文本域控件用來顯示目前音量,因為它和random類裡的str_volume(或者是str_vol_way2以及str_vol_way3)屬性做了綁定,是以它會即時更新音量變化的數值;而文本域控件下方的刻度條控件可以讓使用者更改音量大小(從0 到 100),它和random類的屬性volume綁定起來,是以改變刻度就會帶來volume屬性值的變化,相當于對volume屬性做寫者操作哦。有童鞋可能不明白文本域是如何随着刻度條值的變化而變化的,畢竟他們綁定的不是一個屬性啊!

    其實我在這裡用了kvo的概念,不過這裡我用自己監視的是自己的屬性啊:在random的init方法中設定被觀察者為self,而觀察者也是self,觀察的keypath為@"volume",于是乎若刻度條将volume改變(因為它和volume綁定,是以它刻度的改變會導緻volume的改變,上面已經說了,會調用volume的寫者方法。),則self,也就是random的對象自己會收到通知。不過這裡要注意,不能夠直接在通知回調方法中直接寫:str_volume

= [新值] ,因為你這樣沒有調用str_volume的寫者方法,你是直接改執行個體變量本身了,這樣文本域不會有變化的:因為文本域控件也對str_volume做了kvo,而且該kvo隻能監視到str_volume被寫者方法改變的情況,你直接改它執行個體變量,自然沒有反應喽。要解決這個問題,可以有3種方法:

1 将str_volume定義在interface,并聲明屬性,然後在implementation裡做@synthesize str_volume,這樣我們用[self setstr_volume或self.str_volume的方法(執行個體變量str_volume的寫者方法)修改,自然會通知外部監控器。

2 手動發送通知,告知屬性被改了,這也是str_vol_way2的方法;

3 用屬性的kvc方式修改其值,這也是str_vol_way3的方法啊(注意:str_vol_way3沒有外部接口哦!)。

然後在人語發聲之前用speech的setvolume方法應用目前的音量大小就可以啦,不過注意該方法setvolume的參數是浮點數,取值範圍為0.0 - 1.0,是以我在代碼中要除以100啊!

    再看視窗右上方的清單視圖控件,也有幾個地方要注意:

1 它是由幾個控件組成的,滑鼠要多選幾次才能選中裡面的控件,如果控件選的不對,可能就找不到要設定屬性喽:

obj-c程式設計15[Cocoa執行個體02]:KVC和KVO的實際運用

2 其connections inspector中要連接配接2個地方:datasource和delegate。前者用來做資料源的代理,後者做其本身動作的代理哦。如果不設定前者則沒有資料源,就沒東西顯示啊;同理,若不設定後者就無法響應使用者的動作哦。切記切記。這裡再說說代理,代理就是你調用别的類,可是有些事還是你自己最清楚,是以别的類的有些操作還是得傳回來問你自己啊。比如清單視圖控件對于[col,row]位置顯示的内容是不知道的,是以你必須以回調方法的方式告訴它;再者,如果它的目前選中行發生變化了,他也不知道如何處理,是以也要問你,等于是一個目前行改變的事件發生了,random類必須提供事件處理函數哦。

    最後,nstableview控件還是要按老規矩和random類連接配接起來啊,就在其referencing outlets裡哦;也就是說它和random一共發生了3種顯式關系(想歪的自覺面壁去

obj-c程式設計15[Cocoa執行個體02]:KVC和KVO的實際運用

)如下圖所示:

obj-c程式設計15[Cocoa執行個體02]:KVC和KVO的實際運用

    好了,上面把主要的問題都大緻說過了,啥也不說鳥,下面的都在代碼裡喽(在cocoa執行個體02的代碼基礎上修改而來):

繼續閱讀