iOS總結(jié)

1.分類的加載處理過程

  1. 通過Runtime加載某個類的所有Category數(shù)據(jù)
  2. 把所有Category的方法、屬性泽本、協(xié)議數(shù)據(jù)岔激,合并到一個大的數(shù)組中(這個大的數(shù)組是一個二維數(shù)組)漾月,后面參與編譯的Category數(shù)據(jù)會在數(shù)組的前面
  3. 將合并后的分類數(shù)據(jù)(方法熊泵、屬性、協(xié)議)箕般,插入到類的原來的數(shù)據(jù)的前面耐薯。
    因為以上所以分類的方法會覆蓋類里面的相同名字的方法,但是不是真正的覆蓋,只是最先遍歷到的是分類里面的方法

2.Category的實現(xiàn)原理

  1. Category編譯之后的底層結(jié)構(gòu)是struct category_t,里面存儲著分類的對象方法曲初、類方法体谒、屬性、協(xié)議信息
  2. 在程序運行的時候,runtime會將Category的數(shù)據(jù),合并到類信息中(類對象臼婆、元類對象中)

3. Category和Class Extension的區(qū)別是什么?

  • Class Extension在編譯的時候,他的數(shù)據(jù)就已經(jīng)包含在類信息中(編譯期已經(jīng)合并到類信息中了)
  • Category是在運行時,才會將數(shù)據(jù)合并到類信息中

4. Load方法的調(diào)用

  1. load方法會在runtime加載類,分類的時候調(diào)用(也就是在程序運行的時候調(diào)用)
  2. 每個類,分類的load方法在程序運行的過程中只會調(diào)用一次
  3. load方法的調(diào)用順序
     1. 先調(diào)用類的load方法
      * 按照編譯先后順序調(diào)用(先編譯,先調(diào)用)
      * 調(diào)用子類的load方法之前會先調(diào)用父類的load方法
     2. 再調(diào)用分類的load方法
      * 按照編譯先后順序調(diào)用(先編譯,先調(diào)用)
    
  4. +load方法可以繼承,但是一般不會主動調(diào)用(系統(tǒng)調(diào)用+load方法的時候沒有用到消息發(fā)送機制,而是直接找到的+load方法的地址來直接調(diào)用的)

5. +Initialize的調(diào)用

  1. +Initialize 會在類第一次接收到消息的時候調(diào)用
    • 先調(diào)用父類的+ initalize,再調(diào)用子類的+ initialize,但是它也遵循消息發(fā)送機制,即如果分類中實現(xiàn)了+ initalize,那么就會覆蓋原來類的+ initalize,原來類的+ initalize就不會被調(diào)用.
    • 先初始化父類,再初始化子類,每個類只會初始化一次
      *+ initalize的調(diào)用再源碼中,會在每次對象調(diào)用方法前去判斷,當前類的+ initalize方法是否被調(diào)用過,如果沒有被調(diào)用過就判斷他的父類的+ initalize方法是否被調(diào)用,沒有調(diào)用就先調(diào)用父類的+ initalize,再調(diào)用自己的+ initalize方法,如果都調(diào)用過了接下來走正常的消息發(fā)送機制.
    • initalize和+load的很大區(qū)別是,+ initalize查找過程后的調(diào)用是通過objc_msgSend進行調(diào)用的,所以有以下特點
      * 如果子類沒有實現(xiàn)+ initalize,會調(diào)用父類的+ initalize(所以父類的+ initalize可能會被調(diào)用多次)
      * 如果分類實現(xiàn)了+ initalize,就會覆蓋類本身的+ initalize的調(diào)用
      

6. Block

  1. block本質(zhì)
    • block本質(zhì)上是一個OC對象,它內(nèi)部也有一個isa指針
    • block是封裝了函數(shù)調(diào)用以及函數(shù)調(diào)用環(huán)境的OC對象
  2. block捕獲變量
    • 局部變量(atuo,static)的捕獲,auto變量的捕獲是值傳遞,static捕獲是地址傳遞,這樣捕獲的原因是auto變量可能會銷毀,所以只能是值傳遞
    • 全局變量,block內(nèi)部不會捕獲,因為全局變量,任何地方都能訪問,所以不需要捕獲


      WX20201012-112136@2x.png
    • self 也會被block所捕獲,self也是局部變量,因為self本身就是地址,所以他也是值傳遞
  3. block 的類型
    • 沒有訪問auto變量的是global類型
    • 訪問了auto變量是stack類型
    • stack類型調(diào)用copy后變?yōu)閙alloc類型


      Block調(diào)用copy.png
Block類型.png
  1. block的copy
    在ARC環(huán)境下,編譯器會鞥局情況自動將棧上的block復(fù)制到堆上,比如以下情況
    • block作為函數(shù)的返回值時
    • 將block賦值給__strong指針時
    • block作為Cocoa API中方法名含有usingBlock的方法的參數(shù)時
    • block作為GCD API的方法參數(shù)時
  2. block對象類型的auto變量的捕獲


    對象類型的auto的變量.png
  3. __block修飾符
    • __block可以用于解決block內(nèi)部無法修改auto變量值的問題
    • __block 不能修飾全局變量,靜態(tài)變量
    • 編譯器會將__block修飾的變量包裝成一個對象
  4. 被__block 修飾的對象類型
    • 當__block變量在棧上時,不會對指向的對象產(chǎn)生強引用
    • 當__block變量被copy到堆上時
      1. 會調(diào)用__block變量內(nèi)部的copy函數(shù)
      2. copy 函數(shù)內(nèi)部會調(diào)用_Block_object_assign函數(shù)
      3. _Block_object_assign函數(shù)會根據(jù)所指向的對象的修飾符(__strong,__weak,__unsafe_unretaind)做出相應(yīng)的操作,形成強引用或者弱引用(注意: 這里僅限ARC時會retain,MRC時不會retain)
    • 如果__block變量從堆上移除
      1. 會調(diào)用__block變量內(nèi)部的dispose函數(shù)
      2. dispose 函數(shù)內(nèi)部會調(diào)用_Block_object_dispose函數(shù)
      3. _Block_object_dispose函數(shù)會自動釋放指向的對象(release)
  5. block的循環(huán)引用
    • 可以用___weak或者__unsafe_unretianed來解決循環(huán)引用的問題
    • 他們的不同點
      __weak:  不會產(chǎn)生強引用,指向的對象銷毀時,會自動讓指針置為nil
      __unsafe_unretianed不會產(chǎn)生強引用,不安全,因為當指向的對象銷毀時,指針不會置為nil,指針存儲的地址不變,會產(chǎn)生野指針的問題
      
    • 使用__block也能解決循環(huán)引用的問題,但是必須要調(diào)用block,并且要在block內(nèi)部將變量置為nil,因為__block修飾的變量會被包裝成一個對象,這個對象內(nèi)部對變量有一個強引用,對象本身對被包裝的__block對象有一個強引用,會形成一個三角引用,需要調(diào)用block后,并且在block的調(diào)用內(nèi)部將變量置為nil,才會打破這種循環(huán)引用.
  6. block的屬性修飾詞為什么是copy?使用block有哪些注意?
    • block一旦沒有進行copy操作,就不會在堆上,就不能自己控制他的生命周期
    • 使用注意: 要注意循環(huán)引用
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末抒痒,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子颁褂,更是在濱河造成了極大的恐慌评汰,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件痢虹,死亡現(xiàn)場離奇詭異,居然都是意外死亡主儡,警方通過查閱死者的電腦和手機奖唯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來糜值,“玉大人丰捷,你說我怎么就攤上這事〖呕悖” “怎么了病往?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長骄瓣。 經(jīng)常有香客問我停巷,道長,這世上最難降的妖魔是什么榕栏? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任畔勤,我火速辦了婚禮,結(jié)果婚禮上扒磁,老公的妹妹穿的比我還像新娘庆揪。我一直安慰自己,他們只是感情好妨托,可當我...
    茶點故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布缸榛。 她就那樣靜靜地躺著,像睡著了一般兰伤。 火紅的嫁衣襯著肌膚如雪内颗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天医清,我揣著相機與錄音起暮,去河邊找鬼。 笑死,一個胖子當著我的面吹牛负懦,可吹牛的內(nèi)容都是我干的筒捺。 我是一名探鬼主播,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼纸厉,長吁一口氣:“原來是場噩夢啊……” “哼系吭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起颗品,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤肯尺,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后躯枢,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體则吟,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年锄蹂,在試婚紗的時候發(fā)現(xiàn)自己被綠了氓仲。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡得糜,死狀恐怖敬扛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情朝抖,我是刑警寧澤啥箭,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站治宣,受9級特大地震影響急侥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜炼七,卻給世界環(huán)境...
    茶點故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一缆巧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧豌拙,春花似錦陕悬、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至唯绍,卻和暖如春拼岳,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背况芒。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工惜纸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓耐版,卻偏偏與公主長得像祠够,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子粪牲,可洞房花燭夜當晚...
    茶點故事閱讀 43,440評論 2 348