iOS 使用位段為你的協(xié)議實現(xiàn)緩存功能

在設計接口的時候,委托是常用的交互方式,一般的,我們在使用協(xié)議時會寫出以下代碼。

if ([delegate respondsToSelector:@selector(someMothod:)]) {
        [delegate someMothod:(id)sender];
    }

一般情況下沒有問題,事實上,以上代碼可以滿足大部分的需求,但是假設你所實現(xiàn)的協(xié)議方法是一個類似網(wǎng)絡下載進度回調(diào)的功能,每隔很短的小段時間就需要回調(diào)一次呢?

你會發(fā)現(xiàn),除了第一次檢測委托對象是否響應某個選擇子有意義外,之后的檢測都是多余的。如果委托對象本身沒變,那么不大可能會忽然不能響應某個選擇子。鑒于此,我們可以把委托對象能否響應某個協(xié)議方法這一信息緩存起來,已優(yōu)化程序效率。

假設現(xiàn)在有一個進度回調(diào)的協(xié)議方法

- (void)networkDidUpdateProgressTo:(float)progerss;

以上方法由于需要監(jiān)聽進度,需要頻繁地回調(diào)progress參數(shù),如果能夠緩存委托對象能否響應的信息,我們就不必每次都去執(zhí)行以下函數(shù)

if ([delegate respondsToSelector:@selector(someMothod:)])

將方法相應能力緩存起來的最佳途徑就是使用C語言的“位段”數(shù)據(jù)類型。

這里簡單介紹一下位段:
什么是位段呢? 位段是 C 語言特有的數(shù)據(jù)結(jié)構(gòu), 它允許我們定義一個由位組成的段, 并可為它賦以一個名字。
二進制位是數(shù)據(jù)的基本單位,它比字節(jié)還小,一個字節(jié)由 8 位組成, 而在某些計算機系統(tǒng)中則可能是 16 位。
事實上,如果需要標志一個信息,一位就足夠了,但是由于字節(jié)是存儲的最小單位,所以所有的變量至少要使用一個字節(jié)(比如BOOL值)。
如果我們想在一個很大的表中存儲很多標志, 那么 "被浪費" 的內(nèi)存空間是很可觀的。幸運的是,在 C 語言中, 我們可以使用叫做位段的構(gòu)造類型來定義一個結(jié)構(gòu)體,從而定義某個字段所用的二進制位個數(shù)為某個特定的值。

struct data{                           //包含位段的結(jié)構(gòu)體
    unsigned int fieldA : 8;    //位段fieldA,占8二進制位
    unsigned int fieldB : 4;    //位段fieldB,占4二進制位
    unsigned int fieldC : 2;    //位段fieldC,占2二進制位
    unsigned int fieldD : 1;    //位段fieldD,占1二進制位
}
//位段列表的形式為: 類型說明符 位域名:位域長度

以上結(jié)構(gòu)體中,fieldA 位段將占用 8 個二進制位,fieldB 則為 4個,以此類推。于是,fieldA 可以表示 0 至 255 之間的值,而fieldD可以表示 0 或 1 這兩個值。

我們可以像 fieldD 這樣,把委托對象是否實現(xiàn)了協(xié)議中的相關方法這一信息緩存起來。如果創(chuàng)建的結(jié)構(gòu)體中只有大小為 1 的位段,那么就能把很多 Boolean 值塞入一小塊數(shù)據(jù)里面了(原來存一個BOOL值的空間,現(xiàn)在能存8個),我們現(xiàn)在文件中聲明一個結(jié)構(gòu)體。

struct {
    unsigned int delegateMothod1 : 1;
    unsigned int delegateMothod2 : 1;
    unsigned int delegateMothod3 : 1;
}  _delegateFlags;

然后重寫我們的delegate的setter方法:

-(void)setDelegate:(id<personalDelegate>)delegate
{
    _delegate=delegate;
    _delegateFlags.delegateMothod1=[delegate respondsToSelector:@selector(delegateMothod1:)];
    _delegateFlags.delegateMothod2=[delegate respondsToSelector:@selector(delegateMothod2:)];
    _delegateFlags.delegateMothod3=[delegate respondsToSelector:@selector(delegateMothod3:)];
}

現(xiàn)在委托對象如果能夠相應協(xié)議方法,位段就可以將其以一位的大小緩存起來,然后我們在之后調(diào)用委托對象的相關方法時,就不用檢測委托對象是否能響應給定的選擇子了,而是直接查詢結(jié)構(gòu)體里的標志:

if (_delegateFlags._delegateFlags.delegateMothod1){
    [_delegate delegateMothod1:];
}

在相關方法要調(diào)用很多次的時候,值得進行這種優(yōu)化,而是否需要優(yōu)化,則應依照具體代碼來定。這需要分析代碼性能,并找出瓶頸,若發(fā)現(xiàn)執(zhí)行速度需要改進,則可使用此技巧。如果要頻繁通過數(shù)據(jù)源協(xié)議從數(shù)據(jù)源中獲取多分相互獨立的數(shù)據(jù),那么這項優(yōu)化技術(shù)極有可能會提高程序效率。

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

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

  • 國家電網(wǎng)公司企業(yè)標準(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 12,306評論 6 13
  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,582評論 30 472
  • 從三月份找實習到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時芥藍閱讀 42,757評論 11 349
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內(nèi)部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,626評論 18 399
  • 早上經(jīng)彭老師確認沒有下雨,我蹬上運動鞋,背上小包包,準備步行上班,到了樓下一看,明明淅淅瀝瀝下著雨,趕緊跑上樓...
    癟癟元子閱讀 299評論 1 3

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