設(shè)計模式-MVC模式和KVC/KVO模式以及單例模式的理解記錄

MVC模式:

M: model 是數(shù)據(jù)模型
V: view 是視圖
C: controller 是控制器

一張圖解釋MVC

model 與view 不能直接交互产上,需要通過controller來同步
model負(fù)責(zé)數(shù)據(jù)和狀態(tài)的更新弟断,view顯示給用戶看的內(nèi)容

如何通信:

  • controller到model: 導(dǎo)入model類啄寡,實(shí)例化model對象机杜,進(jìn)行數(shù)據(jù)同步
    controller到view: 在controller中創(chuàng)建View的控件outlet屬性進(jìn)行通信

  • view到controller: 不能在view類中實(shí)例化controller碌冶,需要使用target: action目標(biāo)動作機(jī)制或者delegate委托機(jī)制實(shí)現(xiàn)通信
    target:action:用戶在view上觸發(fā)事件盅藻,view會產(chǎn)生一個action動作朱盐,在controller中群嗤,通過addtarget:方法,接受action動作兵琳。controller自身設(shè)置target狂秘,view在需要通知controller時向controller發(fā)送action
    delegate: controller作為view的被委托者,代理闰围。為view 提供顯示需要的數(shù)據(jù)
    分為動作類delegate:在controller中響應(yīng)action動作和data source數(shù)據(jù)源類delegate:為view 提供需要顯示的數(shù)據(jù)

  • model到controller: 不能在model類中實(shí)例化controller赃绊,因為model不知道有多少個controller引用它。
    需要使用通知機(jī)制和KVO模式和controller通信
    Notification: model自己設(shè)置一個通知中心NSNotificationCenter羡榴,需要知道m(xù)odel數(shù)據(jù)變化的的controller自己注冊一個通知addObserver來監(jiān)聽model的數(shù)據(jù)數(shù)據(jù)變化碧查,讓不需要監(jiān)聽model需要移除注冊監(jiān)聽
    KVO: 使用addObserver:forKeyPath:option:context:方法和removeObserver:forKeyPath:方法來對model設(shè)置和移除注冊監(jiān)聽

MVC模式的優(yōu)勢:

  1. 低耦合性
  2. 高重用性
  3. 可適用性
  4. 可維護(hù)性

MVVM的簡單理解:

MVVM模式是MVC模式的增強(qiáng),把MVC中controller里的表示model給view顯示數(shù)據(jù)的表示邏輯部分提取出來了——view model
MVVM 即 model view viewcontroller view model

單例模式:

應(yīng)用程序中的類只擁有一個實(shí)例:
NSApplication NSFileManager NSBundle UserDefault VIAccelermeter
單例易于訪問

實(shí)現(xiàn)單例:

  1. 在類的內(nèi)部提供一個static修飾的全局變量
  2. 提供一個類方法,方便外界訪問
  3. 重寫+allocWithZone方法忠售,保證永遠(yuǎn)都只為單例對象分配一次內(nèi)存空間
  4. 重寫-copyWithZone方法和-MutableCopyWithZone方法

KVC模式:

KVC概念::KeyValueCoding 鍵值編碼

KVC可以直接通過字符串類型的屬性名key來訪問某個類屬性的機(jī)制传惠,支持對象和基本數(shù)據(jù)類型(自動封裝,解裝)不是通過調(diào)用的Setter稻扬、Getter方法訪問
關(guān)鍵方法定義在 NSKeyValueCodingProtocol

KVC用法:

獲取值

- valueForKey:卦方,傳入NSString屬性的名字。
- valueForKeyPath:泰佳,傳入NSString屬性的路徑盼砍,xx.xx形式。
- valueForUndefinedKey它的默認(rèn)實(shí)現(xiàn)是拋出異常逝她,可以重寫這個函數(shù)做錯誤處理浇坐。

修改值

- setValue:forKey:
- setValue:forKeyPath:
- setValue:forUndefinedKey:
- setNilValueForKey: 當(dāng)對非類對象屬性設(shè)置nil時,調(diào)用黔宛,默認(rèn)拋出異常近刘。
一對多關(guān)系成員的情況
- mutableArrayValueForKey:有序一對多關(guān)系成員 NSArray
- mutableSetValueForKey:無序一對多關(guān)系成員 NSSet

鍵值驗證(Key-Value Validation)

KVC提供屬性值確認(rèn)的API,它可以用來檢查set的值是否正確臀晃、為不正確的值做一個替換值或者拒絕設(shè)置新值并返回錯誤原因
調(diào)用核查方法:
- validateValue:forKey:error:觉渴,默認(rèn)實(shí)現(xiàn)會搜索 validate<Key>:error:格式的核查方法,找到則調(diào)用徽惋,未找到默認(rèn)返回YES

集合操作:

集合操作通過對valueForKeyPath:傳遞參數(shù)來使用案淋,一定要用在集合(如:array)上,否則產(chǎn)生運(yùn)行時刻錯誤寂曹。其格式如下:
Left keypath部分:需要操作對象路徑哎迄。
Collectionoperator部分:通過@符號確定使用的集合操作回右。
Rightkey path部分:需要進(jìn)行集合操作的屬性隆圆。

  • 數(shù)據(jù)操作
    @avg:平均值
    @count:總數(shù)
    @max:最大
    @min:最小
    @sum:總數(shù)
    確保操作的屬性為數(shù)字類型,否則運(yùn)行時刻錯誤翔烁。
  1. 對象操作
    針對數(shù)組的情況
    @distinctUnionOfObjects:返回指定屬性去重后的值的數(shù)組
    @unionOfObjects:返回指定屬性的值的數(shù)組渺氧,不去重
    屬性的值不能為空,否則產(chǎn)生異常蹬屹。
  2. 數(shù)組操作
    針對數(shù)組的數(shù)組情況
    @distinctUnionOfArrays:返回指定屬性去重后的值的數(shù)組
    @unionOfArrays:返回指定屬性的值的數(shù)組侣背,不去重
    @distinctUnionOfSets:同上,只是返回值為NSSet

KVC鍵值查找(搜索單值成員)

- setValue:forKey:搜索方式

1慨默、首先搜索setKey:方法贩耐。(key指成員變量名,首字母大寫)
2厦取、上面的setter方法沒找到潮太,如果類方法accessInstanceVariablesDirectly返回YES。那么按 _key,_isKey铡买,key更鲁,iskey的順序搜索成員名。(NSKeyValueCodingCatogery中實(shí)現(xiàn)的類方法奇钞,默認(rèn)實(shí)現(xiàn)為返回YES)
3澡为、如果沒有找到成員變量,調(diào)用setValue:forUnderfinedKey:

- valueForKey:的搜索方式

1景埃、首先按getKey媒至,key,isKey的順序查找getter方法谷徙,找到直接調(diào)用塘慕。如果是BOOL、int等內(nèi)建值類型蒂胞,會做NSNumber的轉(zhuǎn)換
2图呢、上面的getter沒找到,查找countOfKey骗随、objectInKeyAtindex蛤织、KeyAtindexes格式的方法。如果countOfKey和另外兩個方法中的一個找到鸿染,那么就會返回一個可以響應(yīng)NSArray所有方法的代理集合的NSArray消息方法
3指蚜、還沒找到,查找countOfKey涨椒、enumeratorOfKey摊鸡、memberOfKey格式的方法。如果這三個方法都找到蚕冬,那么就返回一個可以響應(yīng)NSSet所有方法的代理集合
4免猾、還是沒找到,如果類方法accessInstanceVariablesDirectly返回YES囤热。那么按 _key猎提,_isKey,key旁蔼,iskey的順序搜索成員名
5锨苏、再沒找到,調(diào)用valueForUndefinedKey

KVC實(shí)現(xiàn)分析:

KVC運(yùn)用了isa-swizzing技術(shù)棺聊。isa-swizzing就是類型混合指針機(jī)制伞租。KVC通過isa-swizzing實(shí)現(xiàn)其內(nèi)部查找定位。isa指針(is kind of 的意思)指向維護(hù)分發(fā)表的對象的類限佩,該分發(fā)表實(shí)際上包含了指向?qū)崿F(xiàn)類中的方法的指針和其他數(shù)據(jù)葵诈。
例如:
[site setValue:@"sitename" forKey:@"name"];
//會被編譯器處理成

IMP method = objc_msg_loopup(site->isa,sel);
method(site,sel,@"sitename",@"name");```
每個類都有一張方法表,是一個hash表,值是還書指針I(yè)MP驯击,SEL的名稱就是查表時所用的鍵烁兰。

SEL數(shù)據(jù)類型:查找方法表時所用的鍵。定義成char*徊都,實(shí)質(zhì)上可以理解成int值沪斟。
IMP數(shù)據(jù)類型:他其實(shí)就是一個編譯器內(nèi)部實(shí)現(xiàn)時候的函數(shù)指針。當(dāng)Objective-C編譯器去處理實(shí)現(xiàn)一個方法的時候暇矫,就會指向一個IMP對象主之,這個對象是C語言表述的類型

### KVC的內(nèi)部機(jī)制:

一個對象在調(diào)用setValue的時候進(jìn)行了如下操作:
1. 根據(jù)方法名找到運(yùn)行方法的時候需要的環(huán)境參數(shù)
2. 他會從自己的isa指針結(jié)合環(huán)境參數(shù),找到具體的方法實(shí)現(xiàn)接口李根。
3. 再直接查找得來的具體的實(shí)現(xiàn)方法


## KVO模式

### KVO概念:鍵值觀察Key-Value-Observer就是觀察者模式
觀察者模式的定義:一個目標(biāo)對象管理所有依賴于它的觀察者對象槽奕,并在它自身的狀態(tài)改變時主動通知觀察者對象。這個主動通知通常是通過調(diào)用各觀察者對象所提供的接口方法來實(shí)現(xiàn)的房轿。觀察者模式較完美地將目標(biāo)對象與觀察者對象解耦

### KVO實(shí)現(xiàn)步驟:
1. 注冊監(jiān)聽

//keyPath就是要觀察的屬性值
//options給你觀察鍵值變化的選擇
//context方便傳輸你需要的數(shù)據(jù)
-(void)addObserver:(NSObject *)anObserver
forKeyPath:(NSString *)keyPath
options:(NSKeyValueObservingOptions)options
context:(void *)context

2. 實(shí)現(xiàn)監(jiān)聽
  ```//change里存儲了一些變化的數(shù)據(jù)粤攒,比如變化前的數(shù)據(jù),變化后的數(shù)據(jù)囱持;
  //如果注冊時context不為空夯接,這里context就能接收到
  -(void)observeValueForKeyPath:(NSString \*)keyPath
                     ofObject:(id)object
                       change:(NSDictionary \*)change
                      context:(void \*)context
  1. 移除監(jiān)聽

使用觀察者模式需要被觀察者的配合,當(dāng)被觀察者的狀態(tài)發(fā)生變化的時候通過事先定義好的接口(協(xié)議)通知觀察者纷妆。在KVO的使用中我們并不需要向被觀察者添加額外的代碼盔几,就能在被觀察的屬性變化的時候得到通知

KVO實(shí)現(xiàn)步驟分析:

  1. 當(dāng)類A的對象第一次被觀察的時候,系統(tǒng)會在運(yùn)行期動態(tài)創(chuàng)建類A的派生類掩幢。我們稱為B逊拍。
  2. 在派生類B中重寫類A的setter方法,B類在被重寫的setter方法中實(shí)現(xiàn)通知機(jī)制际邻。
  3. 類B重寫會 class方法芯丧,將自己偽裝成類A。類B還會重寫dealloc方法釋放資源枯怖。
  4. 系統(tǒng)將所有指向類A對象的isa指針指向類B的對象注整。

KVO同KVC一樣能曾,通過 isa-swizzling 技術(shù)來實(shí)現(xiàn)度硝。當(dāng)觀察者被注冊為一個對象的屬性的觀察對象的isa指針被修改,指向一個中間類寿冕,而不是在真實(shí)的類蕊程。其結(jié)果是,isa指針的值并不一定反映實(shí)例的實(shí)際類驼唱。

所以不能依靠isa指針來確定對象是否是一個類的成員藻茂。應(yīng)該使用class方法來確定對象實(shí)例的類

使用KVO的幾種方法:

  • 使用了KVC
    使用了KVC,如果有訪問器方法,則運(yùn)行時會在訪問器方法中調(diào)用will/didChangeValueForKey:方法辨赐;
    沒用訪問器方法优俘,運(yùn)行時會在setValue:forKey方法中調(diào)用will/didChangeValueForKey:方法。
  • 有訪問器方法
    運(yùn)行時會重寫訪問器方法調(diào)用will/didChangeValueForKey:方法掀序。
    因此帆焕,直接調(diào)用訪問器方法改變屬性值時,KVO也能監(jiān)聽到不恭。
  • 顯示調(diào)用will/didChangeValueForKey:方法叶雹。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市换吧,隨后出現(xiàn)的幾起案子折晦,更是在濱河造成了極大的恐慌,老刑警劉巖沾瓦,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件满着,死亡現(xiàn)場離奇詭異,居然都是意外死亡贯莺,警方通過查閱死者的電腦和手機(jī)漓滔,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乖篷,“玉大人响驴,你說我怎么就攤上這事∷喊” “怎么了豁鲤?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長鲸沮。 經(jīng)常有香客問我琳骡,道長,這世上最難降的妖魔是什么讼溺? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任楣号,我火速辦了婚禮,結(jié)果婚禮上怒坯,老公的妹妹穿的比我還像新娘炫狱。我一直安慰自己,他們只是感情好剔猿,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布视译。 她就那樣靜靜地躺著,像睡著了一般归敬。 火紅的嫁衣襯著肌膚如雪酷含。 梳的紋絲不亂的頭發(fā)上鄙早,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機(jī)與錄音椅亚,去河邊找鬼限番。 笑死,一個胖子當(dāng)著我的面吹牛呀舔,可吹牛的內(nèi)容都是我干的扳缕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼别威,長吁一口氣:“原來是場噩夢啊……” “哼躯舔!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起省古,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤粥庄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后豺妓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體惜互,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年琳拭,在試婚紗的時候發(fā)現(xiàn)自己被綠了训堆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡白嘁,死狀恐怖坑鱼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情絮缅,我是刑警寧澤鲁沥,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站耕魄,受9級特大地震影響画恰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吸奴,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一允扇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧则奥,春花似錦考润、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至档泽,卻和暖如春俊戳,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背馆匿。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工抑胎, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人渐北。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓阿逃,卻偏偏與公主長得像,于是被迫代替她去往敵國和親赃蛛。 傳聞我的和親對象是個殘疾皇子恃锉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容