不再hook setDelegate和setDataSource
TABAnimated從起初的版本開(kāi)始,為了對(duì)UITableView
和UICollectionView
進(jìn)行弱管理,采取了hook的方式,其中包含UITableView和UICollectionView的setDelegate
和setDataSource
方法。
后來(lái),發(fā)現(xiàn)使用xib/sb創(chuàng)建的UITableView/UICollectionView,在關(guān)聯(lián)代理對(duì)象的時(shí)候,并不會(huì)調(diào)用setDelegate
和setDataSource
方法。這里筆者認(rèn)為,這種方式只是將指針地址改變,蘋(píng)果工程師對(duì)xib/sb進(jìn)行了一定的管理。
與此同時(shí),未免部分開(kāi)發(fā)者會(huì)在開(kāi)啟動(dòng)畫(huà)前多次設(shè)置
了不同源代理,所以這樣的技術(shù)方案存在一定的安全隱患
,是不合理的。
在最新的版本中,將相關(guān)的代理方法的hook時(shí)機(jī)延遲到了目標(biāo)視圖第一次啟動(dòng)TABAnimated骨架屏的時(shí)候。
適配自適應(yīng)高度是如何做的?
答:實(shí)際上采用的是,為代理對(duì)象手動(dòng)加入heightForRowAtIndexPath
這一實(shí)例方法,讓其在動(dòng)畫(huà)時(shí),遵循指定高度規(guī)則,在動(dòng)畫(huà)結(jié)束后,遵循自動(dòng)高度規(guī)則。
在此過(guò)程中發(fā)現(xiàn)了一個(gè)值得關(guān)注的問(wèn)題
答:發(fā)現(xiàn)在進(jìn)行addMethod,交換IMP地址,這些操作后,只有首次加載不走heightForRowAtIndexPath
方法,也就是在第一次就沒(méi)辦法按照我們說(shuō)好的規(guī)則運(yùn)行:在動(dòng)畫(huà)時(shí),遵循指定高度規(guī)則,在動(dòng)畫(huà)結(jié)束后,遵循自動(dòng)高度
。
是什么原因造成的?解決方案是什么?
有個(gè)關(guān)鍵要素,為什么通過(guò)hook setDelegate 的方式,首次加載就可以呢?
隨后,筆者打印了緩存的方法列表,發(fā)現(xiàn)在首次交換方法后,heightForRowAtIndexPath
也是存在于方法列表中的。
而之前hooksetDelegate
方法,在交換了方法后,又對(duì)delegate
重新進(jìn)行了賦值操作。因此,筆者在此時(shí)對(duì)UITableView重新賦值delegate,問(wèn)題得以解決。
結(jié)論:同xib/sb那個(gè)問(wèn)題一樣,xib/sb在切換源代理的時(shí)候,并不會(huì)走setDelegate
和setDataSource
方法。
OC基于方法列表本身有一套緩存機(jī)制,在重新賦值delegate后,蘋(píng)果工程師又對(duì)于UITableView/UICollectionView做了相應(yīng)的調(diào)整。