2021-06-19

UI試圖相關(guān)問題

大綱

  • UITableView 相關(guān)
  • 事件傳遞&視圖響應(yīng)
  • 圖像顯示原理
  • 卡頓&掉幀
  • 異步繪制&繪制原理
  • 離屏渲染

重點:

1贤重、重用機制
2寄疏、并發(fā)訪問草添,更新數(shù)據(jù)(1嚷节、子線程同步主線程的操作2啊犬、多線程操作同步到串行隊列執(zhí)行)
3、傳遞和響應(yīng)(傳遞由上到下嫉入,響應(yīng)由下往上)
4焰盗、圖像顯示原理

  • CPU 處理布局,繪制咒林,圖像編解碼熬拒,提交位圖
  • GPU 渲染管線(頂點著色,圖元裝配映九,光柵化梦湘,片段著色,片段處理)

5、處理UI卡頓掉幀的問題

  • 原因 VSync信號來臨時捌议,GPU中不能提交相應(yīng)畫面數(shù)據(jù)(未處理完)

6哼拔、異步繪制 實現(xiàn)了layer的delegate方法,即可進行異步繪制displayLayer

Object-C特性

大綱

  • 分類
  • 關(guān)聯(lián)對象
  • 擴展
  • 代理
  • 通知
  • KVO
  • KVC
  • 屬性關(guān)鍵字

重點

分類:

  • 運行時決議
  • 可以為系統(tǒng)類添加分類
  • 添加 1瓣颅、實例方法 2倦逐、 類方法 3、協(xié)議 4宫补、屬性
  • 最后編譯的分類方法優(yōu)先生效
  • 分類添加的方法“覆蓋”原類方法
  • 名字相同的分類會引起編譯報錯

關(guān)聯(lián)兌現(xiàn):

  • 為分類所添加的成員變量不會被添加到宿主類上檬姥,而是關(guān)聯(lián)到AssocitationsManager管理(HashMap)

擴展:

  • 用擴展生命私有屬性
  • 用擴展生命私有方法
  • 用擴展生命私有成員變量
  • 編譯時決議
  • 只以聲明的形式存在
  • 不能為系統(tǒng)類添加擴展

代理

  • 軟件設(shè)計模式
  • @protocol
  • 一對一

通知:

  • 一對多
  • 使用觀察者模式實現(xiàn),用于跨層傳遞消息的機制

KVO

  • 觀察者模式的一種實現(xiàn)
  • isa混寫技術(shù)來實現(xiàn)KVO(修改監(jiān)聽對象的isA指針的指向)
  • 手寫KVO valueWillChanged粉怕、valueDidChanged

KVC

  • key value coding
  • 先判斷有沒有屬性方法健民,如果沒有,則判斷有無實例變量贫贝,如也沒有則報錯

屬性關(guān)鍵字

  • atomic
  • nonatomic
  • assign/week
  • copy

Runtime

大綱

  • 數(shù)據(jù)結(jié)構(gòu)
  • 類對象與原類對象
  • 消息傳遞
  • 方法緩存
  • 消息轉(zhuǎn)發(fā)
  • Method-Swizzling
  • 動態(tài)添加方法
  • 動態(tài)方法解析

數(shù)據(jù)結(jié)構(gòu)

  • objc_object
    結(jié)構(gòu)體: isa_t秉犹、關(guān)于isa操作相關(guān)、弱引用相關(guān)稚晚、關(guān)聯(lián)對象相關(guān)崇堵、內(nèi)存管理相關(guān)
  • objc_class
    結(jié)構(gòu)體:suoerClass指針、cache_t cache(方法緩存)客燕、class_data_bits_t(只讀信息鸳劳,協(xié)議,屬性也搓,方法)
  • method_t
    名稱赏廓,返回值,參數(shù)还绘,函數(shù)體
    const char* types => Type Encodings
    返回值 參數(shù)1 參數(shù)2 ... 參數(shù)n
    只讀信息中:name 原生方法列表 成員變量 屬性 協(xié)議
  • 對象楚昭、類對象栖袋、原類對象(關(guān)系)

消息傳遞

void objc_mgsSend(Void /* id self, SEL op, .../)
void objc_mgsSendSuper(Void /
struct objc_super super, SEL op, .../)

消息轉(zhuǎn)發(fā)流程

resolveInstanceMethod: 返回YES 消息處理結(jié)束 拍顷,返回NO forwardingargetForSelector: 返回轉(zhuǎn)發(fā)目標, 返回nil methodSignatureForSelector: 返回方法簽名塘幅,返回nil 報錯

Method-Swizzling

  • 方法交換

動態(tài)添加方法

  • class_addMethod: 接受對象昔案,函數(shù)名,方法簽名

動態(tài)方法解析

  • @dynamic

內(nèi)存管理

大綱

  • 內(nèi)存布局
  • 內(nèi)存管理方案
  • 數(shù)據(jù)結(jié)構(gòu)
  • ARC & MRC
  • 引用計數(shù)
  • 弱引用
  • 自動釋放池
  • 循環(huán)引用

內(nèi)存布局

  • 棧(向下增大)
  • 堆(向上增大)
  • 未初始化數(shù)據(jù)
  • 已初始化數(shù)據(jù)
  • 代碼段

內(nèi)存管理方案
iOS是怎樣管理內(nèi)存的电媳?

  • TaggedPointer
  • NONPOINTER_ISA (非指針型isa)
  • 散列表(弱引用表和引用計數(shù)表)

NONPOINTER_ISA
散列表

  • SideTavles() 結(jié)構(gòu) 踏揣,是一個哈希表,是一個多張表匾乓,可以實現(xiàn)分離鎖

怎樣實現(xiàn)快速分流
使用hash表查找捞稿,提高查找效率

數(shù)據(jù)結(jié)構(gòu)
散列表的數(shù)據(jù)結(jié)構(gòu)

  • Spinlock_t 自旋鎖
  • RefcountMap 引用計數(shù)表
  • weak_table_t 弱引用表

Spinlock_t

  • 是一個“忙等”的鎖。
  • 適用于輕量訪問

RefcountMap

  • 是一個hashMap
  • 使用hash查找為了提高引用效率

weak_table_t

  • 是一個hashMap
  • 存儲了弱引用對象的指針

MRC

手動引用計數(shù)

  • alloc 分配內(nèi)存空間
  • retain 引用計數(shù)加一
  • release 引用計數(shù)減一
  • retainCount 獲取對象的引用計數(shù)
  • autorelease 在autoreleasePool結(jié)束的時候調(diào)用release
  • dealloc 調(diào)用super dealloc

ARC

自動引用

  • ARC是LLVM和Runtime協(xié)作的結(jié)果
  • ARC新增了weak、strong屬性關(guān)鍵字

引用計數(shù)管理

alloc實現(xiàn)

調(diào)用了c函數(shù)的calloc
此時并沒有增加retainCount為1

retain

  • 查找對象的SideTable表
  • 從SideTable表中獲取當前對象的引用計數(shù)值
  • 對引用計數(shù)值進行+1操作

release

  • 查找SideTable
  • 從SideTable表中獲取當前對象的引用計數(shù)值
  • 對引用計數(shù)值進行-1操作

retainCount

  • 查找SideTable
  • 從SideTable表中獲取當前對象的引用計數(shù)值
  • 若不存在引用計數(shù)娱局,則對引用計數(shù)值進行+1操作

dealloc
當前對象是否可以直接釋放一句以下判斷條件

  • nonpointer_isa
  • weakly_referenced
  • has_assoc 是否有關(guān)聯(lián)對象
  • has_cxx_dtor 是否有C++內(nèi)容彰亥,或是否使用arc管理內(nèi)存
  • has_sidetable_rc 當前對象的引用計數(shù)是否通過sidetable表維護的

以上全部為否才可以調(diào)用C函數(shù)直接釋放
否則就要調(diào)用object_dispose() 進行釋放

object_dispose

  • 開始
  • objc_destructInstance(): c++釋放、移除關(guān)聯(lián)對象衰齐、將弱引用指針置位nil任斋、清除引用計數(shù)
  • c函數(shù)free()
  • 結(jié)束

弱引用管理
添加弱引用變量的流程

  • objc_initWeak()
  • storeWeak()
  • weak_register_no_lock()
    1 通過對象指針hash計算查找
    2 如果已經(jīng)存在了弱引用數(shù)組,則添加
    3 如果沒有耻涛,則創(chuàng)建弱引用數(shù)組

清除weak變量废酷,同事設(shè)置為nil

  • dealloc
  • 。抹缕。澈蟆。
  • weak_clear_no_lock()

自動釋放池

  • runloop將要結(jié)束時調(diào)用pop操作
  • 多層嵌套就是多次插入哨兵對象
  • 在for循環(huán)中alloc創(chuàng)建了較大的內(nèi)存消耗是,可手動插入autoReleasePool來釋放內(nèi)存對象

循環(huán)引用

  • 自循環(huán)引用
  • 相互循環(huán)應(yīng)用
  • 多循環(huán)引用

考點

  • 代理
  • Block
  • NSTimer
  • 大環(huán)引用

如何破除

  • 避免產(chǎn)生
  • 在合適的時機手動破除循環(huán)引用

__weak
__block(ARC下會被強引用)
__unsafe_unretained 修飾對象不會增加引用計數(shù)卓研,但是會產(chǎn)生懸垂指針

解決NSTimer的循環(huán)引用問題
NSTimer會被Runloop引用丰介,所以必須手動釋放NSTimer來解除引用。
采用中間對象鉴分,同時弱引用NSTimer和對象哮幢,當對象被釋放后,NSTimer回調(diào)后志珍,判斷弱引用對象已經(jīng)釋放為nil橙垢,此時則invalidate timer,將NSTimer置位nil伦糯,此時NSTimer也被成功釋放柜某。

Block

大綱

  • Blokc介紹
  • 截獲變量
  • __block修飾符
  • Block的內(nèi)存管理
  • Block的循環(huán)引用

Block = 函數(shù) + 上下文 + 對象
Block截獲變量

Block

  • 全局類型block _NSConcreteGlobalBlock (堆)
  • 棧類型block _NSConcreteStackBlock (棧)
  • 堆類型block _NSConcreteMallocBlock (已初始化數(shù)據(jù)區(qū))

棧:拷貝 -》 堆:拷貝-》 堆(引用計數(shù)器+1)

注意:
使用了__block 修飾的的截獲變量修改,會對block進行copy

多線程

大綱

  • GCD
  • NSOperation
  • NSThread
  • 多線程與鎖

GCD

  • 同步/異步 和 串行/并發(fā)
  • dispatch_barrier_aysnc
  • dispatch_group
  1. 同步/異步 和 串行/并發(fā)
    1.1 dispatch_sync(serial_queue /串行隊列/,, ^{ // 任務(wù) });
    1.2 dispatch_async(serial_queue, ^{ // 任務(wù) });
    1.3 dispatch_sync(concurrent_queue /并發(fā)隊列/, ^{ // 任務(wù) });
    1.4 dispatch_async(concurrent_queue, ^{ // 任務(wù) });

  2. dispatch_barrier_async
    2.1 如何實現(xiàn)多讀單寫
    dispatch_barrier_async(concurrent_queue, ^{ // 寫操作 });

  3. dispatch_group
    3.1 A,B,C三個任務(wù)完成后敛纲,再執(zhí)行D

NSOperation

  1. NSOperationQueue
    1.1 可以添加任務(wù)依賴
    1.2 可以添加任務(wù)執(zhí)行狀態(tài)
    1.3 可以控制最大并發(fā)量

任務(wù)執(zhí)行狀態(tài)

  • isReady
  • isExcuting
  • isFinished
  • isCancelled

狀態(tài)控制

  1. 只重寫main時喂击,則無法控制狀態(tài)
  2. 重寫了start,自行控制任務(wù)狀態(tài)

通過KVO來監(jiān)聽NSOperation狀態(tài)

NSThread

  • 如何實現(xiàn)常駐線程
  • Start方法內(nèi)部實現(xiàn)機制(開啟線程淤翔,執(zhí)行函數(shù)翰绊,關(guān)閉線程)

多線程和鎖

  • NSRecursiveLock
  • NSLock
  • dispatch_semaphore_t
@synchronized

單例對象

atomic

原子性賦值

OSSpinLock

自旋鎖(循環(huán)等待訪問,不釋放當前資源)

NSLock
NSRecursiveLock

遞歸鎖旁壮,可以重注

dispatch_semaphore_t

信號量

RunLoop

大綱

  • 概念
  • 數(shù)據(jù)結(jié)構(gòu)
  • 事件循環(huán)機制
  • RunLoop與NSTimer
  • RunLoop與多線程

什么是RunLoop

RunLoop是通過內(nèi)部維護的事件循環(huán)來對事件/消息進行管理的一個對象

  • 維護事件循環(huán)
  • 處理事件和消息的
  • 對象
  1. 事件循環(huán)
  • 沒有消息處理時监嗜,休眠以避免資源占用
  • 有消息需要處理時,立刻喚醒
  • main函數(shù)中抡谐,開啟了運行循環(huán)裁奇,保證函數(shù)不會被結(jié)束,等待 ≠ 死循環(huán)

數(shù)據(jù)結(jié)構(gòu)

  • NSRunLoop => Foundation
  • CFRunLoop => CoreFoundation

CFRunLoop:

  • name: 某一個runloopMode的名稱麦撵,通過名稱來找到模式
  • sources0: CFRunLoopSource => source0 手動喚醒
  • sources1: source1 具備喚醒線程的能力
  • observers: 觀測時間點
  • timers:runloop的定時器

1 RunLoop -> n Model:

  • m Source
  • m Timer
  • m Observer

事件循環(huán)的實現(xiàn)機制

  1. 即將進入RunLoop
  2. 將要處理Timer/Source0事件
    通知Observer
  3. 處理Source0事件
  4. 如果有Source1要處理 -> 8. 處理喚醒時收到的消息
  5. 線程將要休眠
  6. 休眠刽肠、等待喚醒
    6.1 Source1
    6.2 Timer事件的回調(diào)
    6.3 外部手動喚醒
  7. 線程剛被喚醒
  8. 即將退出RunLoop

RunLoop的核心

RunLoop與NSTimer

NSCommonMode

RunLoop與多線程

  • 線程和RunLoop是一一對應(yīng)的
  • 新建的線程默認是沒有RunLoop的

怎樣實現(xiàn)一個常駐線程

  1. 創(chuàng)建一個RunLoop
  2. 添加port/source給RunLoop
  3. 啟動RunLoop

網(wǎng)絡(luò)

大綱

HTTP協(xié)議
HTTPS與網(wǎng)絡(luò)安全
TCP/UDP

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末溃肪,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子音五,更是在濱河造成了極大的恐慌乍惊,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件放仗,死亡現(xiàn)場離奇詭異润绎,居然都是意外死亡,警方通過查閱死者的電腦和手機诞挨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進店門莉撇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人惶傻,你說我怎么就攤上這事棍郎。” “怎么了银室?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵涂佃,是天一觀的道長。 經(jīng)常有香客問我蜈敢,道長辜荠,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任抓狭,我火速辦了婚禮伯病,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘否过。我一直安慰自己午笛,他們只是感情好,可當我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布苗桂。 她就那樣靜靜地躺著药磺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪煤伟。 梳的紋絲不亂的頭發(fā)上癌佩,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天,我揣著相機與錄音持偏,去河邊找鬼驼卖。 笑死氨肌,一個胖子當著我的面吹牛鸿秆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播怎囚,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼卿叽,長吁一口氣:“原來是場噩夢啊……” “哼桥胞!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起考婴,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤贩虾,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后沥阱,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缎罢,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年考杉,在試婚紗的時候發(fā)現(xiàn)自己被綠了策精。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡崇棠,死狀恐怖咽袜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情枕稀,我是刑警寧澤询刹,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站萎坷,受9級特大地震影響凹联,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜哆档,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一匕垫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧虐呻,春花似錦象泵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至朗涩,卻和暖如春忽孽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背谢床。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工兄一, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人识腿。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓出革,卻偏偏與公主長得像杂曲,于是被迫代替她去往敵國和親贡茅。 傳聞我的和親對象是個殘疾皇子坛掠,可洞房花燭夜當晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容

  • (答案不唯一辅鲸,僅供參考,文章最后有福利) 一. iOS面試題---UI相關(guān):事件傳遞展箱,圖像顯示旨枯,性能優(yōu)化,離屏渲染...
    ios南方閱讀 2,658評論 0 12
  • 類 分類的作用混驰? 聲明私有方法攀隔,分解體積。分類的特點栖榨? 運行時決議竞慢,可以為系統(tǒng)類添加分類分類可以添加哪些內(nèi)容?分類...
    Alex1989閱讀 2,101評論 0 26
  • 做這個的初心是希望能鞏固自己的基礎(chǔ)知識治泥,也通過這種方式檢查自己知識的缺失點筹煮。目前還不完善,后續(xù)會根據(jù)時間不斷更正和...
    lp_lp閱讀 35,330評論 7 147
  • 內(nèi)存管理 1.什么情況使用weak關(guān)鍵字居夹,相比assign有什么不同败潦? 什么情況使用 weak 關(guān)鍵字?在 ARC...
    刺骨寒閱讀 671評論 0 1
  • UIKit 1.UIView 和 CALayer 是什么關(guān)系准脂? UIView 繼承 UIResponder劫扒,而 U...
    Sephiroth_Ma閱讀 2,202評論 0 25