欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用objc runtime實(shí)現(xiàn)iOS閉環(huán)的懶加載功能

 更新時(shí)間:2019年06月13日 16:37:00   作者:米太白  
利用objc runtime的動(dòng)態(tài)性實(shí)現(xiàn)懶加載可以實(shí)現(xiàn)即可增加又可刪除功能,也可以避免污染類(lèi)型。這篇文章主要介紹了使用objc runtime實(shí)現(xiàn)iOS閉環(huán)的懶加載功能,需要的朋友可以參考下

使用objc runtime實(shí)現(xiàn)懶加載

地址:AutoPropertyCocoa

懶加載形式如下

- (id)lazyloadProperty{

  if(_lazyloadProperty == nil){
  
    _lazyloadProperty = [XClass ...];
  }
  return _lazyloadProperty;
}

一般使用宏定義可以輕松完成。但是沒(méi)有一致性,移植差。

利用objc runtime的動(dòng)態(tài)性實(shí)現(xiàn)懶加載可以實(shí)現(xiàn)即可增加又可刪除功能,也可以避免污染類(lèi)型。該三方彌補(bǔ)了目前沒(méi)有閉環(huán)實(shí)現(xiàn)懶加載三方的空缺。

主要流程:

  1. 實(shí)例或者類(lèi)的懶加載
  2. 如果是實(shí)例對(duì)象則鉤住并修改類(lèi)型將其子類(lèi)化
  3. 對(duì)該類(lèi)型進(jìn)行method swizzling
  4. 如果現(xiàn)在進(jìn)行解綁,則判斷是否是自己實(shí)現(xiàn)的方法.如果是自己實(shí)現(xiàn)的方法->5,否則->6
  5. 調(diào)用method swizzling還原
  6. 刪除這個(gè)類(lèi)型的這個(gè)方法

難點(diǎn):

自己實(shí)現(xiàn)method swizzling

  1.  重新實(shí)現(xiàn)objc1時(shí)代的方法class_removeMethods
  2.  鉤住運(yùn)行時(shí)中的runtimelock,實(shí)現(xiàn)修改類(lèi)型數(shù)據(jù)時(shí)的安全性

我們?cè)賹?shí)現(xiàn)method swizzling時(shí)的兩個(gè)API

OBJC_EXPORT IMP _Nullable
class_replaceMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp, 
          const char * _Nullable types) 
  OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

OBJC_EXPORT void
method_exchangeImplementations(Method _Nonnull m1, Method _Nonnull m2) 
  OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);

不管使用哪種,如果這個(gè)類(lèi)型沒(méi)有實(shí)現(xiàn)該方法而是父類(lèi)實(shí)現(xiàn)的話(huà),就需要?jiǎng)討B(tài)增加一個(gè)方法。動(dòng)態(tài)增加的方法在Objc1時(shí)代,是可以通過(guò)下列方法刪除的:

OBJC_EXPORT void
class_removeMethods(Class _Nullable, struct objc_method_list * _Nonnull)
  OBJC2_UNAVAILABLE;

Objc2時(shí)代之后runtime被重寫(xiě)后沒(méi)有該方法了,并且新的runtime的類(lèi)結(jié)構(gòu)看起來(lái)就沒(méi)打算讓開(kāi)發(fā)者刪除方法,所以這里將過(guò)程記下。

首先看類(lèi)讀寫(xiě)器的結(jié)構(gòu)class_rw_t

struct class_rw_t {
  // Be warned that Symbolication knows the layout of this structure.
  uint32_t flags;
  uint32_t version;

  const class_ro_t *ro;

  method_array_t methods;//刪除這里的一個(gè)方法
  property_array_t properties;
  protocol_array_t protocols;

  Class firstSubclass;
  Class nextSiblingClass;

  char *demangledName;

#if SUPPORT_INDEXED_ISA
  uint32_t index;
#endif
};

method_array_t繼承于list_array_tt<method_t, method_list_t>,它是數(shù)組結(jié)構(gòu)。存儲(chǔ)的內(nèi)容是method_list_t.

method_list_t又繼承于entsize_list_tt<method_t, method_list_t, 0x3>,他也是數(shù)組結(jié)構(gòu)。

整個(gè)method_array_t結(jié)構(gòu)是二維數(shù)組。每次刪掉一個(gè)method_t需要用新method_list_t替換原對(duì)象。

 

然后是線(xiàn)程安全的問(wèn)題,需要獲取到蘋(píng)果在操作類(lèi)型的時(shí)候使用的讀寫(xiě)鎖(pthread_rw_lock_t runtimelock)。沒(méi)有這把鎖任何對(duì)runtime的修改都是不可靠的。

最終采取的方式是:劫持暴露了符號(hào)的系統(tǒng)函數(shù)然后阻塞線(xiàn)程

 

劫持系統(tǒng)C函數(shù)使用的是臉書(shū)的魚(yú)鉤,這個(gè)鉤子在macOS其實(shí)也是可以正常工作的。

剩下的就是尋找合適的函數(shù)了,這函數(shù)要滿(mǎn)足兩個(gè)條件:

  1. 該函數(shù)在符號(hào)表中存在
  2. 函數(shù)內(nèi)部在lock runtimelock之后存在滿(mǎn)足條件1的第二個(gè)函數(shù)

找了半天發(fā)現(xiàn)最合適的只有objc_allocateProtocol()了,objc_allocateProtocol內(nèi)部會(huì)調(diào)用calloc(),所以第二個(gè)被劫持函數(shù)就是calloc。為了減小calloc的開(kāi)銷(xiāo),需要稍微做一些工作。

  1. 對(duì)每次調(diào)用進(jìn)行比較線(xiàn)程ID的操作顯然比暴力阻塞線(xiàn)程好。
  2. 減小劫持后的calloc的調(diào)用棧。

總結(jié)

以上所述是小編給大家介紹的使用objc runtime實(shí)現(xiàn)iOS閉環(huán)的懶加載功能,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)歡迎給我留言,小編會(huì)及時(shí)回復(fù)大家的!

相關(guān)文章

  • iOS動(dòng)畫(huà)特效之立方體翻轉(zhuǎn)

    iOS動(dòng)畫(huà)特效之立方體翻轉(zhuǎn)

    今天起為大家?guī)?lái)iOS動(dòng)畫(huà)特效合集之立方體翻轉(zhuǎn),APP如美女,動(dòng)畫(huà)如衣裳,趕緊為她披上漂亮的衣裝吧!
    2016-08-08
  • iOS中創(chuàng)建表格類(lèi)視圖WBDataGridView的實(shí)例代碼

    iOS中創(chuàng)建表格類(lèi)視圖WBDataGridView的實(shí)例代碼

    這篇文章主要介紹了iOS中創(chuàng)建表格類(lèi)視圖WBDataGridView的實(shí)例代碼,需要的朋友可以參考下
    2017-02-02
  • Swift項(xiàng)目集成QQ授權(quán)登錄

    Swift項(xiàng)目集成QQ授權(quán)登錄

    這篇文章主要介紹了Swift項(xiàng)目集成QQ授權(quán)登錄的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2021-11-11
  • 詳解iOS App中UIPickerView滾動(dòng)選擇欄的添加方法

    詳解iOS App中UIPickerView滾動(dòng)選擇欄的添加方法

    UIPickerView組件在應(yīng)用中選擇地區(qū)等方面的運(yùn)用非常常見(jiàn),能夠提供多列的選擇項(xiàng),下買(mǎi)呢我們就來(lái)詳解iOS App中UIPickerView滾動(dòng)選擇欄的添加方法
    2016-05-05
  • 老生常談iOS應(yīng)用程序生命周期

    老生常談iOS應(yīng)用程序生命周期

    下面小編就為大家?guī)?lái)一篇老生常談iOS應(yīng)用程序生命周期。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-04-04
  • ios Plist文件配置方法

    ios Plist文件配置方法

    下面小編就為大家分享一篇ios Plist文件配置方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-02-02
  • iOS自定義UIDatePicker日期選擇器視圖

    iOS自定義UIDatePicker日期選擇器視圖

    這篇文章主要為大家詳細(xì)介紹了iOS自定義UIDatePicker日期選擇器視圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • 淺談SwiftUI 里面$0是什么意思如何用

    淺談SwiftUI 里面$0是什么意思如何用

    這篇文章主要介紹了淺談SwiftUI 里面$0是什么意思如何用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • 如何實(shí)現(xiàn)IOS_SearchBar搜索欄及關(guān)鍵字高亮

    如何實(shí)現(xiàn)IOS_SearchBar搜索欄及關(guān)鍵字高亮

    本文通過(guò)實(shí)例代碼演示如何實(shí)現(xiàn)IOS搜索欄及搜索關(guān)鍵字高亮,效果很棒,小編覺(jué)得對(duì)大家的學(xué)習(xí)會(huì)很有幫助,現(xiàn)在分享給大家,有需要的可以參考學(xué)習(xí)。
    2016-08-08
  • IOS 粒子系統(tǒng) (CAEmitterLayer)實(shí)例詳解

    IOS 粒子系統(tǒng) (CAEmitterLayer)實(shí)例詳解

    這篇文章主要介紹了IOS 粒子系統(tǒng) (CAEmitterLayer)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2016-09-09

最新評(píng)論