iOS 通過 NSHashTable 和 NSPointerArray 實(shí)現(xiàn)一對(duì)多代理

在 iOS 程序開發(fā)中,代理(協(xié)議)作為重要的數(shù)據(jù)傳遞手段頻頻被使用,但是代理有一個(gè)弊端,只能一對(duì)一傳值,如果有一個(gè)事件需要眾多類全部能夠被通知到,比如網(wǎng)絡(luò)發(fā)生變化,用戶登錄狀態(tài)發(fā)生變化等,縱然可以用KVO和通知來實(shí)現(xiàn)這樣的功能,但是如何使用代理來實(shí)現(xiàn)呢

可能很多人想到使用數(shù)組來存儲(chǔ)代理

var delegates:[XXDelegate] = []

一行代碼搞定,簡(jiǎn)單完美,但是如果真寫出這樣的代碼,只能說你還需要加深對(duì)“內(nèi)存管理”這個(gè)概念的理解,首先我們談?wù)劄槭裁瓷厦孢@行代碼不可以使用,不過在談這個(gè)問題之前,我們可以聊聊另一個(gè)問題:為什么 iOS 中 IBOutlet 的屬性可以是weak的?

當(dāng)然很多人都知道,這是因?yàn)樽覸iew被加入了self.view.subviews 這個(gè)數(shù)組中,所以可以使用weak,而這也就成了問題的關(guān)鍵:數(shù)組會(huì)強(qiáng)引用加入其中的元素,這也是上面這行代碼不可以使用的原因,那么,如果存在一個(gè)集合類型,他可以弱引用加入其中的元素,不就Ok了

Foundation 還真為我們提供了這樣的結(jié)構(gòu),還提供了三個(gè),分別是NSHashTable,NSMapTable,NSPointerArray,他們對(duì)應(yīng)著我們常用的結(jié)構(gòu):Set,Dictionary,Array,但是它們與常用的這三種結(jié)構(gòu)又有很大的不同。

對(duì)傳統(tǒng)的集合類型,他們有如下缺點(diǎn):

  1. 無法存儲(chǔ)nil (Swift的Array類型可以存儲(chǔ)nil)
  2. 無法對(duì)加入其中的元素進(jìn)行弱引用

而Foundation 提供的這三個(gè)類型,則彌補(bǔ)了上面的缺點(diǎn),使我們可以對(duì)其中的元素進(jìn)行弱引用,達(dá)到一對(duì)多進(jìn)行代理通知的目的。

其基本使用思路和上面提到的是類似的,但是具體代碼上需要做些變化。

private var weakDelegates:NSHashTable<AnyObject> = NSHashTable<AnyObject>(options: NSPointerFunctions.Options.weakMemory)
//注意這里需要使用 weakMemory 選項(xiàng),否則不具有弱引用效果

func addDelegate(delegate:ServerManagerDelegate){
        let object:AnyObject = delegate as AnyObject
        if !self.weakDelegates.contains(object) {
            self.weakDelegates.add(object)
        }
    }

    func removeDelegate(delegate:ServerManagerDelegate){
        let object:AnyObject = delegate as AnyObject
        if self.weakDelegates.contains(object) {
            self.weakDelegates.remove(object)
        }
    }

當(dāng)需要對(duì)全部代理進(jìn)行通知的時(shí)候,我們可以

for i in weakDelegates.allObjects {
            if let delegate:XXDelegate = i as? XXDelegate {
                delegate.foo()
            }
        }

如果需要按照加入代理的時(shí)間順序來進(jìn)行通知,可以使用 NSPointerArray 來實(shí)現(xiàn),代碼都是類似的

如果想要深入了解 NSHashTable,NSMapTable,NSPointerArray,那么你可以看看這篇文章:http://www.saitjr.com/ios/nspointerarray-nsmaptable-nshashtable.html

?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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