iOS-底層原理 10:strong&copy&weak底層分析 以及 方法簽名和attribute簡(jiǎn)寫(xiě)含義

iOS 底層原理 文章匯總

在clang編譯的cpp文件中可以發(fā)現(xiàn) strong & copy & weak 修飾的屬性在編譯的底層代碼中是有區(qū)別的

strong & copy & weak 底層分析

  • 在LGPerson中我們定義了兩個(gè)兩個(gè)屬性,分別用copy和strong修飾


    定義類(lèi)
  • clangmain.m文件編譯成main.cpp,然后發(fā)現(xiàn)copy 和strong修飾的屬性的set方法是有區(qū)別的

    clang編譯后的屬性的set、get方法

這里就有疑問(wèn)了,為什么copy修飾的屬性使用了objc_setProperty,而strong修飾的沒(méi)有

  • 在LLVM中搜索”objc_setProperty,找到如下所示的getOptimizedSetPropertyFn方法中

    objc_setProperty底層編譯

    從這里即可看出,針對(duì)不同的修飾符,返回的那么是不同的

  • 如果是atomic & copy修飾,name為objc_setProperty_atomic_copy

  • 如果是atomic 且沒(méi)有copy修飾,name為 objc_setProperty_atomic

  • 如果是nonatomic & copy 修飾,name為 objc_setProperty_nonatomic_copy

  • 其他剩余的組合,即nonatomic、nonatomic & strong、nonatomic & weak等,name為objc_setProperty_nonatomic

上述的幾個(gè)name分別對(duì)應(yīng)objc-781源碼中的如下方法


對(duì)應(yīng)的objc-781源碼

然后通過(guò)匯編調(diào)試發(fā)現(xiàn),最終都會(huì)走到objc_storeStrong

  • copy修飾的屬性匯編調(diào)試結(jié)果


    copy匯編調(diào)試
  • strong修飾的屬性匯編調(diào)試結(jié)果


    strong匯編調(diào)試
  • 源碼中搜索objc_storeStrong,有如下源碼,主要也是retain新值,release舊值

void
objc_storeStrong(id *location, id obj)
{
    id prev = *location;
    if (obj == prev) {
        return;
    }
    objc_retain(obj);//retain新值
    *location = obj;
    objc_release(prev);//release舊值
}
  • llvm編譯源碼中搜索objc_storeStrong,找到EmitARCStoreStrongCall方法,如下圖所示,發(fā)現(xiàn)copy 和 strong修飾的屬性執(zhí)行的策略是不一致的

    EmitARCStoreStrongCall底層

  • llvm中搜索EmitARCStoreStrongCall方法,在GenerateCopyHelperFunction方法有調(diào)用,然后在這里發(fā)現(xiàn)了strong 和 weak的不同處理

    GenerateCopyHelperFunction底層編譯

    其中BlockCaptureEntityKind有如下的枚舉值以及表示的含義
    BlockCaptureEntityKind枚舉值

    • 如果是weak修飾,執(zhí)行EmitARCCopyWeak方法,如下所示,weak在底層的調(diào)用是 objc_initWeak

      EmitARCCopyWeak底層編譯

    • 如果是strong修飾,執(zhí)行EmitARCStoreStrongCall方法

結(jié)論

  • copystrong修飾的屬性在底層編譯的不一致,主要還是llvm中對(duì)其進(jìn)行了不同的處理的結(jié)果。copy的賦值是通過(guò)objc_setProperty,而strong的賦值時(shí)通過(guò)self + 內(nèi)存平移(即將指針通過(guò)平移移至name所在的位置,然后賦值),然后還原成 strong類(lèi)型

  • strong & copy 在底層調(diào)用objc_storeStrong,本質(zhì)是新值retain,舊值release

  • weak 在底層調(diào)用objc_initWeak

補(bǔ)充知識(shí): Type Encoding & Property Type String

Type Encoding-官方文檔

Property Type String-官方文檔

clang中的方法簽名

Type encoding

clang中編譯后,方法列表的這些字符的含義是什么


clang編譯后的方法列表

@16@0:8為例

  • @16表示返回字符串占用16個(gè)字節(jié) -- 第二個(gè)@8字節(jié), sel8字節(jié)
    • 第一個(gè)@ 表示 返回值
    • 16 表示 總共占用的字節(jié)數(shù)16字節(jié)
    • 第二個(gè)@:第一個(gè)參數(shù)
      • id -- @ 統(tǒng)配類(lèi)型
      • typedef struct objc_object *id
    • 0 -- 從0開(kāi)始 0-8
    • : -- 代表sel,方法編號(hào)
    • 8 -- 8-16
  • 而v24@0:8@16中的 v -- void 無(wú)返回值

更多的可以查看官網(wǎng)的以下列表


Type encoding表

clang編譯后的屬性的attribute

clang編譯輸出了屬性的attribute ,同樣也可以通過(guò)property_getAttributes方法獲取

clang編譯后的attribute

  • T 表示 type
  • @ 表示 變量類(lèi)型
  • C 表示 copy
  • N 表示 nonatomic
  • V 表示 variable 變量,即下劃線(xiàn)變量 _nickName

更多的可以查看官網(wǎng)的以下列表


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

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