使用objcruntime實現(xiàn)iOS怎么閉環(huán)的懶加載功能-創(chuàng)新互聯(lián)

今天就跟大家聊聊有關使用objc runtime實現(xiàn)iOS怎么閉環(huán)的懶加載功能,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據(jù)這篇文章可以有所收獲。

堅守“ 做人真誠 · 做事靠譜 · 口碑至上 · 高效敬業(yè) ”的價值觀,專業(yè)網站建設服務10余年為成都軟裝設計小微創(chuàng)業(yè)公司專業(yè)提供企業(yè)網站建設營銷網站建設商城網站建設手機網站建設小程序網站建設網站改版,從內容策劃、視覺設計、底層架構、網頁布局、功能開發(fā)迭代于一體的高端網站建設服務。

懶加載形式如下

- (id)lazyloadProperty{

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

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

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

主要流程:

  1. 實例或者類的懶加載

  2. 如果是實例對象則鉤住并修改類型將其子類化

  3. 對該類型進行method swizzling

  4. 如果現(xiàn)在進行解綁,則判斷是否是自己實現(xiàn)的方法.如果是自己實現(xiàn)的方法->5,否則->6

  5. 調用method swizzling還原

  6. 刪除這個類型的這個方法

難點:

自己實現(xiàn)method swizzling

  1. 重新實現(xiàn)objc1時代的方法class_removeMethods

  2. 鉤住運行時中的runtimelock,實現(xiàn)修改類型數(shù)據(jù)時的安全性

我們再實現(xiàn)method swizzling時的兩個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);

不管使用哪種,如果這個類型沒有實現(xiàn)該方法而是父類實現(xiàn)的話,就需要動態(tài)增加一個方法。動態(tài)增加的方法在Objc1時代,是可以通過下列方法刪除的:

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

Objc2時代之后runtime被重寫后沒有該方法了,并且新的runtime的類結構看起來就沒打算讓開發(fā)者刪除方法,所以這里將過程記下。

首先看類讀寫器的結構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;//刪除這里的一個方法
  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ù)組結構。存儲的內容是method_list_t.

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

整個method_array_t結構是二維數(shù)組。每次刪掉一個method_t需要用新method_list_t替換原對象。

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

然后是線程安全的問題,需要獲取到蘋果在操作類型的時候使用的讀寫鎖(pthread_rw_lock_t runtimelock)。沒有這把鎖任何對runtime的修改都是不可靠的。

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

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

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

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

  1. 該函數(shù)在符號表中存在

  2. 函數(shù)內部在lock runtimelock之后存在滿足條件1的第二個函數(shù)

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

  1. 對每次調用進行比較線程ID的操作顯然比暴力阻塞線程好。

  2. 減小劫持后的calloc的調用棧。

看完上述內容,你們對使用objc runtime實現(xiàn)iOS怎么閉環(huán)的懶加載功能有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注創(chuàng)新互聯(lián)網站建設公司行業(yè)資訊頻道,感謝大家的支持。

另外有需要云服務器可以了解下創(chuàng)新互聯(lián)建站muchs.cn,海內外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。

文章題目:使用objcruntime實現(xiàn)iOS怎么閉環(huán)的懶加載功能-創(chuàng)新互聯(lián)
文章起源:http://muchs.cn/article18/ejedp.html

成都網站建設公司_創(chuàng)新互聯(lián),為您提供手機網站建設外貿建站、微信公眾號、動態(tài)網站、網站導航、營銷型網站建設

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

成都網站建設