從有道云筆記復(fù)制過來的,沒有任何格式了.不知道用markdown記錄的筆記會(huì)不會(huì)附帶格式,我還不想重新再寫一遍,這就很尷尬
UIView和CALayer
calayer 負(fù)責(zé)顯示內(nèi)容 contents 實(shí)際顯示的東西都是bitmap
面試題 為什么要講顯示和事件分開 設(shè)計(jì)模式中的單一模式原則
響應(yīng)連
事件傳遞鏈 點(diǎn)擊屏幕 -> 事件傳遞到UIApplication -> 傳遞到UIWindow -> 然后同過hittestwithEvent -> 這里又調(diào)用pointInsideWithevent來判斷是否點(diǎn)擊在UIwindow范圍內(nèi) ->是就會(huì)遍歷window的所有子視圖通過hittest值不nil,倒敘遍歷
圖片渲染流程
1定點(diǎn)數(shù)據(jù) 2頂點(diǎn)著色器 3圖元(確定形狀 三角形還是畸形) 4裁剪空間 5光柵化(確定這個(gè)圖元的像素) 6片元著色器(上色)
滑動(dòng)優(yōu)化方案
同時(shí)加載多張大圖 可以監(jiān)聽runloop.一次runloop只加載一張圖,這樣內(nèi)存和性能都會(huì)變好
cpu 可以降低對(duì)象的頻繁創(chuàng)建銷毀,或者是創(chuàng)建放到子線程,還有排版什么也放到子線程
gpu 異步繪制 離屏渲染 圖層避免太過復(fù)雜
1 異步繪制
calayer 有個(gè)代理 displayalyer 是子線程,在這個(gè)代理里面設(shè)置bitmap的一些相關(guān)的問題,最后用bitmap合成CGImage 提交給calayer的content 回到主線程
2 避免離屏渲染 離屏渲染指的是GPU層面,在當(dāng)前屏幕緩沖區(qū)外新開辟一個(gè)緩沖區(qū)來進(jìn)行渲染操作
是指視圖設(shè)置了一些屬性,再未操作之前不能直接顯示到屏幕上,就會(huì)觸發(fā)離屏渲染, 圓角與masktobounds同時(shí)設(shè)置,設(shè)置陰影,mask,光柵化
之所以要避免是因?yàn)樵黾恿薌Pu的工作,這樣在cpu+gpu的工作量就大于每秒60次的刷新,就會(huì)卡頓
分類可以做什么
- 在不創(chuàng)建繼承類的情況下實(shí)現(xiàn)對(duì)已有類的擴(kuò)展
- 能對(duì)大型的類有效分解
- 將常用的相關(guān)方法進(jìn)行分組
- 當(dāng)已知某個(gè)類庫的某個(gè)方法有BUG,我們無法直接修改源代碼的時(shí)候,可以使用Category來替代這個(gè)已有類中某個(gè)方法的實(shí)體,從而達(dá)到修復(fù)BUG的目的
多個(gè)分類中有相同名字的函數(shù)方法,運(yùn)行取決于最后編譯的分類,
分類會(huì)覆蓋掉宿主類的方法 ,因?yàn)檫\(yùn)行的時(shí)候,所有的函數(shù)名在一個(gè)數(shù)組里,分類的函數(shù)靠前,
相同名字的分類 會(huì)編譯報(bào)錯(cuò),類似于宿主類兩個(gè)同名屬性
擴(kuò)展
與分類區(qū)別 分類是運(yùn)行時(shí)確定,擴(kuò)展是編譯時(shí)確定
擴(kuò)展不能為系統(tǒng)類添加方法
關(guān)聯(lián)對(duì)象
所有的關(guān)聯(lián)對(duì)象都存放在一個(gè)全局的容器當(dāng)中 在AssociationsHashMap中存儲(chǔ)
通知
通知是廣播形式 一對(duì)多
Post一個(gè)通知后,經(jīng)由通知中心廣播給所有的observe
實(shí)現(xiàn)一個(gè)通知方法, 單利 維護(hù) 一個(gè)字典, key為通知name ,value存obsver對(duì)象以及相應(yīng)通知的方法名和一些其他參數(shù)
KVO觀察者模式
觀察者模式的內(nèi)部實(shí)現(xiàn)
在對(duì)一個(gè)對(duì)象的屬性實(shí)現(xiàn)監(jiān)聽之后,這個(gè)對(duì)象,會(huì)動(dòng)態(tài)生成一個(gè)派生類,然后將源對(duì)象的isa指針指向新生成的派生類,然后重寫派生類的set方法.然后來達(dá)到通知觀察者的模式
當(dāng)對(duì)象走了addobserver之后,類名就發(fā)生改變
通過kvc方式將對(duì)象屬性進(jìn)項(xiàng)改變,kvo依然能夠監(jiān)聽到 setValue””forKey”keypath”
用_(成員變量)下劃線方式修改屬性 監(jiān)聽不到,因?yàn)橄聞澗€不會(huì)setter
修飾符
原子性 線程安全 賦值取值不會(huì)被線程調(diào)度器中斷
assign 可以修飾基本類型與對(duì)象類型 assign 引用計(jì)數(shù)不加1 weak不能修飾基本類型
copy 只有當(dāng)被拷貝對(duì)象為不可變,拷貝出對(duì)象為不可變的時(shí)候才是淺拷貝
RunTime相關(guān)
Objc_object
所有的id對(duì)象在runtiome中 都是Objc_Object
Class類在runtime中是Objc_class這樣數(shù)據(jù)結(jié)構(gòu) objc_class 繼承與Objc_objec 所以class也是一個(gè)對(duì)象
isa指針
isa指針是isa_t這個(gè)結(jié)構(gòu)體
面試題: isa 含義 ,答案如下
isa_t 有指針型的 isa 和非指針的isa
指針型的isa代表class的地址 非指針型的isa 部分帶表class地址(其余多出來的部分來存儲(chǔ)別的東西來達(dá)到節(jié)約內(nèi)存的目的 尋址過程中用不到64位 用不滿,還有一部分空余)
然后class的指針指向其元類對(duì)象 (MetaClass)
類對(duì)象和元類對(duì)象
類對(duì)象存儲(chǔ)實(shí)例方法列表信息
元類對(duì)象存儲(chǔ)類方法列表信息
catch_t
用于快速查找方法函數(shù)(一個(gè)緩存,可以不用去方法列表里去逐一便利,提高運(yùn)行速度)
是一個(gè)增量擴(kuò)展的哈希表結(jié)構(gòu)(哈希表實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)是為了提高查找效率)
是局部性原理的最佳應(yīng)用 -> 局部性原理是 把調(diào)用率最高的方法放到緩存里
緩存查找 哈希查找 通過方法選擇器 sel 然后通過算出key找到IMP函數(shù)指針返回給調(diào)用者
Class_data_bits_t
主要是對(duì)Class_rw_t的封裝 (rw讀寫)代表了對(duì)類的讀寫的信息還有對(duì)class_ro_t的封裝
Method_t
就是一個(gè)函數(shù)
函數(shù)四要素 名稱 參數(shù) 返回值 函數(shù)體
metdthod_t結(jié)構(gòu)體中含有 SEL name : 代表函數(shù)名稱 const char*type參數(shù)與返回值的組合 IMP:imp 函數(shù)體(一個(gè)無類型的函數(shù)指針)
Runtime整體數(shù)據(jù)結(jié)構(gòu)
方法調(diào)用順序
實(shí)例方法,當(dāng)調(diào)用一個(gè)對(duì)象的實(shí)例方法時(shí),會(huì)通過isa指針找到對(duì)象的類對(duì)象,然后類對(duì)象查緩存方法列表catch_t,沒有就去找全部方法列表,如果沒有,就去類對(duì)象的父類查找,一直到基類.
類方法會(huì)通過isa指針找到元類對(duì)象,然后同上,最后區(qū)別是,當(dāng)元類對(duì)象基類也沒有此方法時(shí),會(huì)通過isa指針找到類對(duì)象的基類,查找是否有對(duì)應(yīng)的實(shí)例方法
方法查找:緩存查找是哈希查找通過sel方法選擇器生成一個(gè)key然后找到對(duì)應(yīng)imp的函數(shù)指針返回,如果緩存中沒有就去方法列表中找,對(duì)于已經(jīng)排序的方法列表通過二分查找,未排序的通過遍歷查找,都沒有就通過superclass指針找到父類對(duì)象,然后在父類對(duì)象中重復(fù)上一操作
面試題
phone繼承于mobile 在phone中調(diào)用[self class]和調(diào)用[super class] 打印是什么
打印結(jié)果都是phone 在[self class]會(huì)通過函數(shù)objcMessageSend這個(gè)函數(shù)調(diào)用,消息傳遞過程中 self為類對(duì)象objc_Object ,objcet isa指針指向類對(duì)象 在類對(duì)象catch方法中找對(duì)應(yīng)的函數(shù),找不到就找superclass中的方法,然后一直到基類nsobject中找到方法
[super closs] 會(huì)調(diào)用objcMessageSendSuper函數(shù),調(diào)用者雖然是super 在運(yùn)行時(shí)中表現(xiàn)為objc_super 然后super中有一個(gè)recever,表示為消息的接受者,其實(shí)還是self ,然后查找方法是會(huì)直接找objc_objcet的類對(duì)象的super class ,也就是跳過當(dāng)前類對(duì)象去向上查找,所以還是phone.
Method_Swizzling 方法交換
動(dòng)態(tài)添加方法
classAddMethod 消息轉(zhuǎn)發(fā)機(jī)制 resolveInstanceMethodSel 參數(shù)是方法選擇器@selector 如果有函數(shù)體返回值,就結(jié)束消息轉(zhuǎn)發(fā) 沒有就就可以動(dòng)態(tài)添加方法,
Dynamic 動(dòng)態(tài)方法
就是在編譯的時(shí)候不確定某個(gè)方法的函數(shù)體,運(yùn)行時(shí)才決議
面試題
1 [obc func]和objc_sendMessage有什么關(guān)系
在編譯后 這個(gè)方法就變成了objc_sendMessage 參數(shù)就是obj和func選擇器
2runtime如果通過@selector找到對(duì)應(yīng)的IMP地址的
通過實(shí)例對(duì)象拿到類對(duì)象,在類對(duì)象的方法緩存中用哈希查找發(fā)查找,沒有就通過super………
3能否向編譯后的類添加實(shí)例變量(不能,這個(gè)時(shí)候),可以在動(dòng)態(tài)添加類的時(shí)候添加實(shí)例變量(動(dòng)態(tài)添加類,點(diǎn)一個(gè)按鈕創(chuàng)建一個(gè)類)
內(nèi)存管理
- isa 64位用一部分存地址,一部分存else
- 散列表
散列表
sideTables內(nèi)含多個(gè)sidetable(64個(gè)) 是一個(gè)哈希表 具有多個(gè)sideTable原因是性能問題 因?yàn)闀?huì)有成千上萬個(gè)對(duì)象,如果在一個(gè)sideTable中操作,會(huì)加鎖解鎖保證線程安全,性能問題 所以用分離??(多個(gè)表)
sideTable 結(jié)構(gòu) 自旋鎖 引用計(jì)數(shù)表 弱引用表
引用計(jì)數(shù)表和弱引用表 也都是一個(gè)哈希表 使用哈希提高查找效率
引用計(jì)數(shù)通過對(duì)指針的函數(shù)查找找到對(duì)應(yīng)的引用計(jì)數(shù)
弱引用通過指針的哈希函數(shù)查找到對(duì)象的地址
面試題: retain實(shí)現(xiàn)原理 通過對(duì)sidetables 哈希查找對(duì)象引用計(jì)數(shù)所在的sideTable,然后在sideTable中同樣用哈希查找找到對(duì)應(yīng)的引用計(jì)數(shù)
對(duì)象釋放 weak指針的變量會(huì)自動(dòng)置為nil 因?yàn)閐ealloc中會(huì)調(diào)用 weak_clear(弱引用清除)的方法 通過對(duì)象指針哈希查找到"弱引用數(shù)組",如果這個(gè)數(shù)組中有,遍歷所有對(duì)象 ,將指針置為nil
ARC
arc是有編譯器llvm在自動(dòng)位置插入代碼和runtime協(xié)作管理內(nèi)存 arc 不能手動(dòng)調(diào)用引用計(jì)數(shù)的方法 mrc可以
自動(dòng)釋放池
1 組成結(jié)構(gòu) 是以棧為節(jié)點(diǎn)的雙線鏈表的形式組合而成
@autoreleasePool{}
編譯之后的形式為
objc_autoreleasePoolPush
{中間為代碼塊
}
objc_autoreleasePoolPop
每一個(gè)自動(dòng)釋放池都是有多個(gè)AutoreleasePoolPage 以雙向鏈表形式組成的
AutoreleasePoolPage是一個(gè)棧,當(dāng)自動(dòng)釋放池初始化的時(shí)候objc_autoreleasePoolPush方法 會(huì)自動(dòng)向棧頂插入一個(gè)哨兵對(duì)象(nil的別稱) 然后再陸續(xù)添加{}中的需要自動(dòng)釋放的對(duì)象 然后 調(diào)用objc_autoreleasePoolPop ,回從棧頂查找一直找到上一個(gè)哨兵對(duì)象的位置,對(duì)著中間的所有對(duì)象執(zhí)行release操作
2 和線程一一對(duì)應(yīng)
問題1 在viewdidiload中創(chuàng)建一個(gè)數(shù)組,這個(gè)數(shù)組什么時(shí)候回被釋放掉 runloop將要結(jié)束的時(shí)候
2 autoRelease 多層嵌套就是底層 增加一個(gè)哨兵對(duì)象
3 什么時(shí)候手動(dòng)創(chuàng)建autoReleasePool 在循環(huán)創(chuàng)建大量臨時(shí)對(duì)象的時(shí)候
http://www.itdecent.cn/p/32265cbb2a26 自動(dòng)釋放池
循環(huán)引用
一共有三種循環(huán)引用
1自循環(huán) 一個(gè)對(duì)象有一個(gè)強(qiáng)引用成員變量 這時(shí)將這個(gè)成員變量賦值為對(duì)象自身,就造成的自循環(huán)
2相互循環(huán) 對(duì)象A有個(gè)強(qiáng)引用B ,B里還有個(gè)強(qiáng)引用A
3多循環(huán) A->B->C->A
如何破除循環(huán)引用
1 主動(dòng)避開循環(huán)引用 weak關(guān)鍵字 2 在適當(dāng)?shù)臅r(shí)機(jī)破環(huán)
具體實(shí)現(xiàn)方法 __weak ( __block 在arc下依然會(huì)增加引用計(jì)數(shù) 所以還需要手動(dòng)破環(huán))
項(xiàng)目中遇到的循環(huán)引用問題 以及解決方案 調(diào)用timerInvalid
NSTImer 一個(gè)VC里弱引用timeer , timer的定時(shí)器回調(diào)會(huì)對(duì)對(duì)象強(qiáng)引用,再有Runloop回對(duì)timer強(qiáng)引用這樣就相當(dāng)于runloop也強(qiáng)引用了對(duì)象 所以問題不是timer和vc之間的強(qiáng)引用,在于runloop一直存在所以timer一直存在所以對(duì)象釋放不掉
http://www.itdecent.cn/p/a1e0dd905a69 NSTimer
解決方法1 選擇合適的時(shí)機(jī)手動(dòng)釋放timer 調(diào)用[self.timer invalidate];
2. timer使用block方式添加Action 避免timertarger強(qiáng)引用vc
3 用一個(gè)中間對(duì)象 VC弱引用中間對(duì)象 中間對(duì)象持有Timer 這樣 中間對(duì)象釋放 指針會(huì)自動(dòng)置為nil
Block相關(guān)
什么是Block? Block是將函數(shù) 上下文封裝起來的對(duì)象
變量截獲 問題
局部變量 block編譯后的結(jié)構(gòu)體中會(huì)自動(dòng)新增類型名稱相同的成員變量 相當(dāng)于swift值類型,靜態(tài)的局部變量(static)是對(duì)其指針截獲
靜態(tài)全局變量、全局變量 不產(chǎn)生截獲
block截獲象類型的變量所有權(quán)和修飾符一并截獲的,并存儲(chǔ)自身的結(jié)構(gòu)體中作為成員變量
如下圖
面試題
此題 將multiplier加上__block后 結(jié)果為8
__block關(guān)鍵字什么時(shí)候使用? 一般情況下對(duì)被截獲的變量進(jìn)行賦值的操作需要加__block修飾符 (賦值操作 array = [new arr]屬于賦值 array.append(E)不是賦值操作)
這道題在于__Block在ARC下會(huì)造成引用計(jì)數(shù)+1 所以 blockSelf 強(qiáng)引用了self 是一個(gè)大閉環(huán)引用, 所以在 block內(nèi)部將blockSelf置位nil
block 為什么會(huì)造成循環(huán)引用 block截獲當(dāng)前對(duì)象實(shí)例變量的時(shí)候會(huì)對(duì)當(dāng)前對(duì)象造成強(qiáng)引用,然后當(dāng)前對(duì)象也強(qiáng)引用block
http://www.itdecent.cn/p/c36f1bb92b03
多線程相關(guān)
同步:只能在當(dāng)前線程中執(zhí)行任務(wù),不具備開啟新線程的能力
異步:可以在新線程中執(zhí)行任務(wù),具備開啟新線程的能力。不一定開辟新線程 (并發(fā)隊(duì)列開多條,系統(tǒng)決定,穿行開一條)
并發(fā): 多個(gè)任務(wù)同事執(zhí)行(只有在異步才有效果) 串行:任務(wù)順序執(zhí)行
只有異步函數(shù)+并發(fā)隊(duì)列才會(huì)并發(fā)執(zhí)行 其余都是串行執(zhí)行
viewdidload 中調(diào)用sync…dispathcGetmain 會(huì)造成死鎖 循環(huán)等待 viewdidload在主線程執(zhí)行中 會(huì)調(diào)用block,等block調(diào)用完成之后,viewdidiload 才會(huì)結(jié)束,而block也是在主隊(duì)列中,隊(duì)列的性質(zhì)就是先進(jìn)先出,必須要等didload結(jié)束才會(huì)走,所以相互等待 如果隊(duì)列不是主隊(duì)列是不會(huì)死鎖的,因?yàn)閮烧卟辉谕魂?duì)列.
柵欄調(diào)用 sync 和async 的區(qū)別是sync是執(zhí)行完在返回 async是先返回再執(zhí)行
dispatch_apply 快速迭代 就是異步線程. 一般io操作文件移動(dòng)什么的耗時(shí)操作 會(huì)用到
Ios中的鎖
@synchronized 互斥鎖 一般在創(chuàng)建單利對(duì)象的時(shí)候 來保證在多線程環(huán)境下 所創(chuàng)建的對(duì)象是惟一的 (缺點(diǎn)比較慢)
atomic 屬性關(guān)鍵字 對(duì)修飾的對(duì)象進(jìn)行原子操作(賦值可以,使用無效) 就是對(duì)setter方法枷鎖
OSSpinLock 自旋鎖 循環(huán)等待訪問,不釋放自身資源
NSLOck
NSRecursiveLock 遞歸鎖
semaphore信號(hào)量
面試題 ios幾種多線程特點(diǎn)
GCD 實(shí)現(xiàn)簡單的線程同步 子線程分配 ,多讀單寫
NSOperation 特點(diǎn)是對(duì)任務(wù)的狀態(tài)進(jìn)行控制 sdweb和af都用的這個(gè)
NSThread 常駐線程
Runloop
什么是runloop 是通過內(nèi)部維護(hù)的 "事件循環(huán)" 來對(duì) 消息/事件處理的一個(gè)對(duì)象
沒有消息處理時(shí)休眠以節(jié)省資源*(內(nèi)核態(tài)) 有消息需要處理時(shí) 喚醒(用戶態(tài)) 用戶態(tài)時(shí)應(yīng)用層面 內(nèi)核態(tài)時(shí)系統(tǒng)層面
數(shù)據(jù)結(jié)構(gòu)
NSRunloop 包裝了CFFunloop,提供了面向?qū)ο蟮腶pi
rp循環(huán)機(jī)制
RL與線程關(guān)系
線程與runloop是一一對(duì)應(yīng)的,但是自己創(chuàng)建的線程是默認(rèn)沒有創(chuàng)建的
問題1 main函數(shù)為什么能保持不退出
main函數(shù)中 會(huì)調(diào)用uiapplactionMian函數(shù) 會(huì)啟動(dòng)主線程的runloop ,runloop是事件循環(huán)的一個(gè)對(duì)象 ,可以做到內(nèi)核態(tài)到用戶態(tài)的切換
2 tableview滑動(dòng)的時(shí)候 定時(shí)器 怎樣才能一直起作用 調(diào)用吃飯runloop addtimer 因?yàn)閞l中有好多個(gè)mode mode里面有source timer observer ,同一時(shí)期只執(zhí)行一個(gè)mode ,我們需要將這個(gè)timer加入到這個(gè)虛 擬的commonmode中
3如何實(shí)現(xiàn)常駐線程
創(chuàng)建一個(gè)線程對(duì)應(yīng)的runloop 第二 向mode中添加source timer obser等內(nèi)容 第三部 調(diào)用run ,釋放的時(shí)候只要remove scorce…就可以 注意!運(yùn)行模式和資源添加模式要是同一個(gè)
4 子線程數(shù)據(jù)回來更新UI不打斷用戶滑動(dòng)操作
將子線程數(shù)據(jù)返回給子線程的時(shí)候,將數(shù)據(jù)提交到default模式,滑動(dòng)式track模式,這樣用戶停止滑動(dòng)的時(shí)候就會(huì)自動(dòng)切換為def 就會(huì)處理數(shù)據(jù)
http://www.itdecent.cn/p/f3079ea36775
nsoperation block等只有加入operationquene里面才會(huì)并發(fā)執(zhí)行開辟線程,或者追加addExecution
operation隊(duì)列可以暫?;謴?fù)取消最大并發(fā)等特點(diǎn) 操作依賴,operA依賴于operB ,B執(zhí)行后再執(zhí)行A .還可以監(jiān)聽operation 的執(zhí)行完畢
網(wǎng)絡(luò)
http 請(qǐng)求行: 方法字段 (post get) URL 協(xié)議版本 頭部字段 (key value ) 實(shí)體主題
響應(yīng)報(bào)文 版本 狀態(tài)碼 狀態(tài)碼描述 首部字段 響應(yīng)主體
HTTP請(qǐng)求方式有幾種
GET POST HEAD PUT DELETE OPTIONS
GET POST 區(qū)別
get參數(shù)是?后拼接到url里面 post是在body里 get參數(shù)有長度限制 post沒有
get 不會(huì)對(duì)server端進(jìn)行操作 冪等性(執(zhí)行一次和多次效果是一樣的) 可緩存 post全返
HTTP鏈接建立流程 三次握手四次揮手
抓包原理 中間人共計(jì) 代理服務(wù)
對(duì)稱加密 加密和解密是同一個(gè)秘鑰 非對(duì)稱加密 加密和解密要分開為公鑰和私鑰.或者私鑰公鑰
設(shè)計(jì)模式
六大設(shè)計(jì)原則 : 1 單一模式原則 比如view和layer 各分其職 一個(gè)類只負(fù)責(zé)一件事,否則就代碼臃腫,可讀性差
2 依賴倒置原則 是程序要依賴于抽象接口,不要依賴于具體實(shí)現(xiàn)。簡單的說就是要求對(duì)抽象進(jìn)行編程,不要對(duì)實(shí)現(xiàn)進(jìn)行編程,這樣就降低了客戶與實(shí)現(xiàn)模塊間的耦合
3 開閉原則 對(duì)組件功能的擴(kuò)展式開放的,對(duì)組件內(nèi)容的修改式關(guān)閉的
4 里氏設(shè)計(jì)原則 父類可以被子類替換,而原有功能不受任何影響 (KVO)
5 接口隔離原則 使用多個(gè)專門的協(xié)議,而不是一個(gè)臃腫的協(xié)議 比如UITable的collec和datasource
6迪米特法則 一個(gè)對(duì)象應(yīng)該對(duì)其他對(duì)象盡可能少了解 高內(nèi)聚低耦合
責(zé)任鏈模式: 鏈表結(jié)構(gòu),參考famey濾鏡實(shí)現(xiàn)
橋接模式: 將抽象部分與它實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立地變化。http://www.itdecent.cn/p/7d8a2aae0041
適配器模式: 將一個(gè)接口轉(zhuǎn)換希望的另一個(gè)接口,使接口不兼容的那些類可以一起工作 也叫包裝模式 有一個(gè)古老的類,進(jìn)行修改的時(shí)候, new一個(gè)新類,將老類作為成員變量.然后對(duì)老類操作,封裝啥的
單例模式: 要重寫allocwithzone 返回shareinstance 來防止外界不使用share方法初始化 重寫copy 防止外界copy單利
命令模式:將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象,從而使你可用不同的請(qǐng)求對(duì)客戶進(jìn)行參數(shù)化 撤銷重做
設(shè)計(jì)一個(gè)圖片緩存框架 manager 內(nèi)存 磁盤 網(wǎng)絡(luò)三方面 然后解碼相關(guān),壓縮解壓縮.注意事項(xiàng) 緩存條數(shù),淘汰策略(時(shí)長,切換后臺(tái)等,lru算法(最近多少分鐘沒有用過)) 網(wǎng)絡(luò)方面最大并發(fā)任務(wù)啥的
時(shí)長統(tǒng)計(jì)
解耦 依賴注入 是一個(gè)將行為從依賴中分離的技術(shù) 一般就是將A的實(shí)力b不在A中創(chuàng)建 而是在A的構(gòu)造函數(shù)中將b作為參數(shù)傳入.