1、UIView和CALayer的區(qū)別
UIView: 為其提供內(nèi)容晦嵌,以及負(fù)責(zé)處理觸摸等事件參與響應(yīng)鏈
CALayar: 負(fù)責(zé)顯示內(nèi)容contents
單一職責(zé)原則(設(shè)計(jì)原則)
2、事件傳遞機(jī)制和視圖響應(yīng)鏈
事件傳遞主要跟兩個(gè)方法有關(guān)系:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
和- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
励堡。點(diǎn)擊圓形區(qū)域艇炎,傳遞過(guò)程可參照下面的流程圖耸成。
這里遍歷時(shí)采用的是倒序遍歷叛拷,若點(diǎn)擊的位置在兩個(gè)視圖的交集舌厨,那么誰(shuí)后添加誰(shuí)接收事件。(即最上面的視圖為最終接收者)忿薇。
響應(yīng)鏈:當(dāng)視圖接收事件后判斷該視圖是否響應(yīng)事件裙椭,若沒(méi)有響應(yīng)該事件則會(huì)逐級(jí)尋找下一個(gè)響應(yīng)者直到UIApplicationDelagate
。如果一直沒(méi)有響應(yīng)該事件署浩,則忽略該事件揉燃。
3、滑動(dòng)視圖優(yōu)化方案以及離屏渲染
首先解釋一下出現(xiàn)卡頓筋栋、掉幀的原因:UI繪制過(guò)程中是CPU/GPU共同協(xié)作的結(jié)果你雌,一般60幀/s為穩(wěn)定狀態(tài)。即需要時(shí)16.7ms內(nèi)實(shí)現(xiàn)一個(gè)Vsync信號(hào)的顯示二汛,若超過(guò)這個(gè)時(shí)間則可理解為掉幀。一般保證30幀以上即卡頓不是很明顯拨拓。
離屏渲染:
- 是GPU在當(dāng)前屏幕的緩沖區(qū)外新開(kāi)一個(gè)緩沖區(qū)進(jìn)行渲染操作肴颊。
- 視圖在設(shè)置某些屬性時(shí)會(huì)被標(biāo)記在未預(yù)合成之前不能在屏幕上顯示。
觸發(fā)離屏渲染:
- 設(shè)置圓角(必須與maskToBounds一起使用)
- 圖層蒙版
- 設(shè)置陰影
- 光柵化
離屏渲染的影響
- 增加GPU的工作量使CPU/GPU的時(shí)間增加出現(xiàn)掉幀渣磷、卡頓
- 創(chuàng)建新的渲染緩沖區(qū)婿着,上下文切換增加額外開(kāi)銷(xiāo)。
4、關(guān)于OC對(duì)象相關(guān)問(wèn)題
① 分類(lèi)的作用
- 聲明私有方法
- 分解體積龐大的類(lèi)文件
- 把Framework的私有方法分開(kāi)
② 分類(lèi)的特點(diǎn)
- 運(yùn)行時(shí)決議(通過(guò)runtime將分類(lèi)信息添加到類(lèi)中)
- 可以為系統(tǒng)類(lèi)添加分類(lèi)(獲取坐標(biāo))
③ 分類(lèi)可添加的內(nèi)容
- 實(shí)例方法竟宋、類(lèi)方法
- 協(xié)議
- 屬性(只會(huì)聲明提完,不會(huì)實(shí)現(xiàn)get、set方法丘侠。)
總結(jié):分類(lèi)是通過(guò)運(yùn)行時(shí)編譯徒欣,將方法、協(xié)議蜗字、屬性添加到類(lèi)的原數(shù)據(jù)之前打肝。如果多個(gè)分類(lèi)實(shí)現(xiàn)同一個(gè)方法,那么誰(shuí)后編譯誰(shuí)先執(zhí)行挪捕。分類(lèi)方法會(huì)存在類(lèi)方法列表前面的位置粗梭,也就是所謂的“覆蓋”。名字相同的分類(lèi)會(huì)引起編譯報(bào)錯(cuò)级零。
④ 關(guān)聯(lián)對(duì)象的使用
為分類(lèi)添加成員變量断医。
所有對(duì)象的關(guān)聯(lián)內(nèi)容全部都存到一個(gè)全局AssociationsHashMap中。內(nèi)部關(guān)系可以參照下方字典的key-value映射關(guān)系奏纪。
{
"0x34245":{
“@selector(key)”:{
"value":"hello",
"policy":"retain"
}
}
}
⑤ 擴(kuò)展
- 聲明私有屬性(防止子類(lèi)調(diào)用)
- 聲明私有方法
- 聲明私有成員變量
- 編譯時(shí)決議鉴嗤。
- 只以聲明的形式存在,多數(shù)情況下寄生于宿主類(lèi)的.m中亥贸。
- 不能為系統(tǒng)類(lèi)添加擴(kuò)展
⑥ 代理Delegate
- 一種軟件設(shè)計(jì)模式躬窜。
- @protocol形式實(shí)現(xiàn)。
- 一對(duì)一
⑦ 通知NSNotification
- 是使用觀察者模式來(lái)實(shí)現(xiàn)的用于跨層傳遞消息的機(jī)制
- 一對(duì)多
- 內(nèi)部實(shí)現(xiàn):作為一個(gè)字典炕置,key為通知名稱(chēng)荣挨,value為observer的集合。
⑥ KVO使用原理
- KVO是觀察者設(shè)計(jì)模式的一種實(shí)現(xiàn)
- 使用了isa混寫(xiě)
(isa-swizzling)
來(lái)實(shí)現(xiàn)KVO
當(dāng)對(duì)A類(lèi)添加觀察者時(shí)朴摊,運(yùn)行時(shí)出產(chǎn)生一個(gè)A類(lèi)的子類(lèi)
NSKVONotifying_A
對(duì)setter
方法重寫(xiě)默垄,來(lái)達(dá)到通知所有觀察者的目的。
-(void) willChangeValueForKey:(NSString *)key
// 原來(lái)的setter方法
[super setValue:]
-(void) didChangeValueForKey:(NSString *)key
- 使用setter方法改變值KVO才會(huì)生效
- 使用KVC也會(huì)觸發(fā)KVO
- 修改成員變量不會(huì)觸發(fā)KVO甚纲】诙В可以進(jìn)行手動(dòng)觸發(fā)(重寫(xiě)子類(lèi)的兩個(gè)方法)
⑦ KVC使用原理
鍵值編碼技術(shù)。
setValue:forKey:
查看setKey _setKey
是否存在介杆,如果不存在判斷-(BOOL)accessInstanceVariablesDirectly
鹃操,返回真則找成員變量 _key,_isKey, key, isKey
進(jìn)行賦值,如果不存在則會(huì)報(bào)錯(cuò)
valueForKey:
查看getKey, Key, isKey, _key
是否存在春哨,如果不存在判斷-(BOOL)accessInstanceVariablesDirectly
荆隘,返回真則找成員變量 _key,_isKey, key, isKey
進(jìn)行取值,如果不存在則會(huì)報(bào)錯(cuò)
⑧ 屬性關(guān)鍵字
- 讀寫(xiě)權(quán)限
readwrite 默認(rèn)
readonly
- 原子性
atomic 默認(rèn)
nonatomic
區(qū)別:
atomic
是線程安全的赴背。加入修飾一個(gè)數(shù)組椰拒,那么數(shù)組的獲取和賦值能保證線程安全晶渠,但是對(duì)數(shù)組的操作不能保證是線程安全的。
- 引用計(jì)數(shù)
retain/strong
assign
weak
copy
assign
:- 修飾基本數(shù)據(jù)類(lèi)型
- 修飾對(duì)象類(lèi)型燃观,不會(huì)改變其引用計(jì)數(shù)
- 會(huì)產(chǎn)生懸垂指針褒脯。(修飾的對(duì)象被釋放,但是指針依然指向原來(lái)的地址)
weak
: - 不改變被修飾對(duì)象的引用計(jì)數(shù)
- 所指對(duì)象在被釋放之后會(huì)自動(dòng)置為nil
淺拷貝和深拷貝:淺拷貝對(duì)地址的復(fù)制缆毁,指向同一塊內(nèi)存地址番川。深拷貝會(huì)產(chǎn)生一個(gè)新的內(nèi)存地址。
淺拷貝會(huì)增加對(duì)象的引用計(jì)數(shù)积锅。
對(duì)可變對(duì)象和不可變對(duì)象進(jìn)行copy
和mutableCopy
:
- 可變對(duì)象的
copy
和mutableCopy
都是深拷貝爽彤。 - 不可變對(duì)象的
copy
是淺拷貝,mutableCopy
是深拷貝缚陷。 -
copy
方法返回的對(duì)象都是不可變對(duì)象适篙。