設(shè)計(jì)模式-觀察者模式

定義

觀察者模式也叫做發(fā)布-訂閱模式,當(dāng)一個(gè)對(duì)象狀態(tài)發(fā)生改變,所以依賴(lài)于他的訂閱者都會(huì)得到通知并自動(dòng)

應(yīng)用場(chǎng)景

關(guān)聯(lián)場(chǎng)景
事件多級(jí)觸發(fā)

這個(gè)可以暫時(shí)理解為響應(yīng)式編程

跨系統(tǒng)消息交互場(chǎng)景

例如:消息隊(duì)列 事件總線 RxSwift RxJava RxAndroid

觀察者模式

KVO ,NSNotification委托Delegate都可以說(shuō)是OC中的監(jiān)聽(tīng)者模式,NSNotification相當(dāng)于更加重量級(jí)一些,除了監(jiān)聽(tīng)還可以負(fù)責(zé)傳遞信息等
下面先很粗略的簡(jiǎn)單介紹下,畢竟之前有專(zhuān)門(mén)寫(xiě)過(guò)KVO ,NSNotification

  • KVO
    KVO是用來(lái)做屬性監(jiān)聽(tīng)的,用完后必須要移除它。

其實(shí)現(xiàn)原理:KVO是基于runtime機(jī)制實(shí)現(xiàn)的,當(dāng)某個(gè)類(lèi)的對(duì)象第一次被觀察時(shí),系統(tǒng)就會(huì)在運(yùn)行期動(dòng)態(tài)的創(chuàng)建一個(gè)該類(lèi)的一個(gè)派生類(lèi),在這個(gè)派生類(lèi)中重寫(xiě)基類(lèi)中任何被觀察屬性的setter方法,派生類(lèi)在重寫(xiě)基類(lèi)的setter方法中實(shí)現(xiàn)真正的通知機(jī)制

上述,就是一個(gè)KVO的完整實(shí)現(xiàn),但事實(shí)上,還是有瑕疵的,潛在的問(wèn)題有可能出現(xiàn)在dealloc中對(duì)KVO的注銷(xiāo)上。KVO的一種缺陷(其實(shí)不能稱(chēng)為缺陷,應(yīng)該稱(chēng)為特性)是,當(dāng)對(duì)同一個(gè)keypath進(jìn)行兩次removeObserver時(shí)會(huì)導(dǎo)致程序crash,這種情況常常出現(xiàn)在父類(lèi)有一個(gè)kvo,父類(lèi)在dealloc中remove了一次,子類(lèi)又remove了一次的情況下

  • NSNotification
    一個(gè)類(lèi)的屬性發(fā)生改變,我們也可以使用NSNotification告訴其他對(duì)象,被改變的具體情況
    這樣,也是可以監(jiān)聽(tīng)到對(duì)象屬性的改變的
    只是說(shuō),需要注意,如果是跨控制器之間的監(jiān)聽(tīng)、或者傳遞信息,建議用NSNotification更好,如果是view與它的ViewController之間的監(jiān)聽(tīng),用委托(也就是delegate)更好

  • KVC
    KVC: key values coding 鍵值編碼,間接通過(guò)字符串對(duì)應(yīng)的key取出、修改其對(duì)應(yīng)的屬性。
    KVC當(dāng)然是強(qiáng)大的,UIKit框架里面很多屬性是readOnly、私有的,往往我們?cè)陂_(kāi)發(fā)中會(huì)覺(jué)得有一些屬性不好用,想改變吧,要么是readOnly,要是是私有的,難道重新寫(xiě)一套?但是耗時(shí)耗力,項(xiàng)目需要趕進(jìn)度的話,就得加班。這個(gè)時(shí)候,KVC的作用就大了,我們可以自定義那些特定需求的控件,然后用KVC將系統(tǒng)自帶的換掉,換成自定義的,簡(jiǎn)單快速輕松就可以搞定了。當(dāng)然,要是系統(tǒng)沒(méi)有對(duì)應(yīng)屬性的控件,就只能自定義了,太多用處了
    作用: 可以訪問(wèn)和修改私有成員變量、readOnly成員變量的值。(替換系統(tǒng)自帶的導(dǎo)航欄、替換系統(tǒng)自帶的Tabbar等

  • 委托 + Delegate
    這個(gè)是我本身代碼里經(jīng)常用到的一種,一般是view與它的ViewController之間的監(jiān)聽(tīng),用委托(也就是delegate),因?yàn)槲乙话鉼i全寫(xiě)在view里,那么view里相關(guān)點(diǎn)擊方法什么的,都是通過(guò)delegate代理到viewcontroller里的

  • 根據(jù)觀察者模式設(shè)計(jì)的代碼
    如上四個(gè)都是語(yǔ)言設(shè)計(jì)里自帶里有關(guān)于觀察者設(shè)計(jì)模式的內(nèi)容,那么如果自己寫(xiě)一個(gè)觀察者模式應(yīng)該怎么做呢
    實(shí)現(xiàn)的基本原理

    image.png

    Subject通過(guò)內(nèi)部數(shù)組observerArr保存觀察者列表,通過(guò)addObserver和removeObserver添加、移除觀察者,當(dāng)Subject對(duì)象狀態(tài)發(fā)生變化的時(shí)候,調(diào)用update方法,update方法遍歷observerArr對(duì)象數(shù)組調(diào)用Observer的update方法通知觀察者,Observer是一個(gè)只有協(xié)議申明的文件

我個(gè)人感覺(jué)有點(diǎn)像多太

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容