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
同步/異步 和 串行/并發(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ù) });dispatch_barrier_async
2.1 如何實現(xiàn)多讀單寫
dispatch_barrier_async(concurrent_queue, ^{ // 寫操作 });dispatch_group
3.1 A,B,C三個任務(wù)完成后敛纲,再執(zhí)行D
NSOperation
- NSOperationQueue
1.1 可以添加任務(wù)依賴
1.2 可以添加任務(wù)執(zhí)行狀態(tài)
1.3 可以控制最大并發(fā)量
任務(wù)執(zhí)行狀態(tài)
- isReady
- isExcuting
- isFinished
- isCancelled
狀態(tài)控制
- 只重寫main時喂击,則無法控制狀態(tài)
- 重寫了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)
- 處理事件和消息的
- 對象
- 事件循環(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)機制
- 即將進入RunLoop
- 將要處理Timer/Source0事件
通知Observer - 處理Source0事件
- 如果有Source1要處理 -> 8. 處理喚醒時收到的消息
- 線程將要休眠
- 休眠刽肠、等待喚醒
6.1 Source1
6.2 Timer事件的回調(diào)
6.3 外部手動喚醒 - 線程剛被喚醒
- 即將退出RunLoop
RunLoop的核心
RunLoop與NSTimer
NSCommonMode
RunLoop與多線程
- 線程和RunLoop是一一對應(yīng)的
- 新建的線程默認是沒有RunLoop的
怎樣實現(xiàn)一個常駐線程
- 創(chuàng)建一個RunLoop
- 添加port/source給RunLoop
- 啟動RunLoop
網(wǎng)絡(luò)
大綱
HTTP協(xié)議
HTTPS與網(wǎng)絡(luò)安全
TCP/UDP