【iOS_Development】delegate的使用優化

前言

相信做過iOS開發的人都使用過delegate(并不是設置模式中的proxy),這里就以一個實例,來分享一下開發中大量使用某個delegate方法的優化方案

位段

位段,C語言允許在一個結構體中以位為單位來指定其成員所占內存長度,這種以位為單位的成員稱為“位段”或稱“位域”( bit field) 。利用位段能夠用較少的位數存儲數據。
struct data {
    unsigned int fieldA : 8;
    unsigned int fieldB : 4;
    unsigned int fieldC : 2;
    unsigned int fieldD : 1;
}

在結構體中,fieldA位段將占用8個二進制位,fieldB占用4個,fieldC占用2個,fieldD占用1個。于是,fieldA可以表示0至255之間的值,而fieldD可以表示0或1這兩個值,我們可以像fieldD這樣,把委托對象是否實現了協議中的相關方法這一信息緩存起來。如果創建結構體中只有大小為1的位段,那么就能把許多Boolean值塞入一小塊數據里面了。以網絡數據獲取器為例,可以在該實例中嵌入一個含有位段的結構體作為其實例變量,而結構體中的每個位段則表示delegate對象是否實現了協議中的相關方法

delegate緩存

@interface NetworkFetcher () {
    struct {
        unsigned int didReceiveData : 1;
        unsigned int didFailWithError : 1;
        unsigned int didUpdateProgressTo : 1;
    }_delegateFlags;
}

@end

上面的實例變量是個結構體,其中含有三個位段,每個位段都與delegate所遵從的協議中某個可選(@optional)方法相對應。這個結構體用來緩存委托對象是否能響應特定的選擇子,實現緩存功能所用的代碼可以寫在delegate屬性所對應的設置方法里

- (void)setDelegate:(id<NetworkFetcherDelegate>)delegate {
    _delegate = delegate;

    _delegate.didReceiveData = [delegate respondsToSelector:@selector(NetworkFetcher:didReceiveData)];
    _delegate.didFailWithError = [delegate respondsToSelector:@selector(NetworkFetcher:didFailWithError)];
    _delegate.didUpdateProgressTo = [delegate respondsToSelector:@selector(NetworkFetcher:didUpdateProgressTo)];    
}

這樣的話,每次調用delegate的相關方法之前,就不用檢測委托對象是否能響應給定的選擇子了,而是直接查詢結構體里的標識

if (_delegate.didUpdateProgressTo) {
    [_delegate NetworkFetcher:self didUpdateProgressTo:currentProgess];
}

在相關方法要調用多次時,值得進行這種優化,而是否需要優化,則應依照具體代碼來定。這就需要分析代碼性能,并找出瓶頸,若發現執行速度需要改進,則可使用該技巧。如果要頻繁通過數據源協議從數據源中獲取多份相互獨立的數據,那么這項優化技術極有可能會提高程序效率


聲明:本文摘自《Effective Objective C 2.0:編寫高質量iOS與OS X代碼的52個有效方法》


GitHub主頁

CSDN Blog

Email:jinjob@icloud.com

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容