一面問題匯總:
iOS基本知識:
1.OC語言層面乎澄,runtime,isa指針测摔,消息機制
2.UI置济,布局,動畫锋八,事件傳遞和響應鏈浙于,控制器聲明周期
3.多線程,網(wǎng)絡
4.copy挟纱,KVC,KVO,block羞酗,代理,設計模式紊服,優(yōu)化
5.MVC,MVVM
6.數(shù)據(jù)持久化檀轨,UserDefult,歸解檔欺嗤,SQlite(FMDB)
4.三方庫参萄,推送APNS,分享
5.cocoapods、git煎饼、svn
性能優(yōu)化:
1.卡頓優(yōu)化 減少CPU,GPU資源消耗讹挎,防止出現(xiàn)離屏渲染
2.耗電優(yōu)化 網(wǎng)絡請求,定位吆玖,渲染筒溃,I/O,少用定時器
3.啟動優(yōu)化
冷啟動三個階段:
動態(tài)鏈接:裝在Mach-O 文件和動態(tài)庫。減少動態(tài)庫衰伯,類和分類數(shù)量
runtime:+load,注冊類积蔚,初始化類對象
main: 耗時操作不要放在這
4.包大小優(yōu)化
5.弱網(wǎng)環(huán)境優(yōu)化
屏幕成像原理:CPU負責布局計算意鲸,圖片格式轉換和解碼;GPU負責圖像的渲染;然后屏幕垂直同步怎顾,成像
如果屏幕發(fā)起垂直同步读慎,GPU還沒有渲染完成,就會造成卡頓槐雾。
CPU職責:對象創(chuàng)建和銷毀夭委,屬性調整,布局計算募强,文本計算排版株灸,圖片解碼、繪制擎值、格式轉換慌烧,
GPU職責:紋理渲染
離屏渲染:GPU有兩種渲染模式,當前屏幕渲染和離屏渲染鸠儿,將離屏緩沖區(qū)的渲染結果顯示到屏幕上屹蚊,上下文環(huán)境從離屏切換到當前屏幕,這個過程會造成性能的消耗
以下操作會造成離屏渲染:
光柵化进每,layer.shouldRasterize = YES
遮罩汹粤,layer.mask
圓角,同時設置 layer.masksToBounds = YES田晚,layer.cornerRadius > 0
陰影嘱兼,如果設置了 layer.shadowPath 不會產(chǎn)生離屏渲染
TableView優(yōu)化
0.cell復用
1.緩存行高
2.延遲加載,在scrollerView中停止?jié)L動的代理方法中添加[self.imageView performSelector:@selector(setImage:) withObject:[UIImage imageNamed:@"tupian"] afterDelay:4.0 inModes:@[NSDefaultRunLoopMode]]
3.切圓角肉瓦,遮罩遭京,陰影效果會造成離屏渲染
4.減少層級關系,少用透明泞莉,減少圖片分辨率
block:
block是一個預先準備好的代碼塊哪雕,本質是結構體
分類:
1.全局block 內(nèi)部沒有引用外部變量的 Block
2.棧block block 內(nèi)部引用外部變量
3.堆block
Block從棧中復制到堆的情況:
調用Block的copy實例方法時
Block作為函數(shù)返回值返回時
在帶有usingBlock的Cocoa方法或者GCD的API中傳遞Block時候
將block賦給帶有__strong修飾符的id類型或者Block類型時
默認 引用外部變量 引用static變量
類: 全局區(qū); 棧 全局
對象:棧鲫趁; 堆區(qū) 全局
引用外部變量的傳遞方式:
一般數(shù)據(jù)類型:值截獲
局部靜態(tài)變量:指針截獲
全局變量:直接引用全局變量
__block原理:
__block修飾的變量變成了一個結構體對象斯嚎,block內(nèi)部修改的變量是__block修飾變量結構體的成員
forwarding指針是外部變量的被__block修飾后,指向堆結構體的指針
對象類型的外部變量挨厚,對象類型的結構體里面多了copy和dispose兩個函數(shù)
屬性修飾區(qū)別:
weak堡僻,正常使用沒有問題,如果重新初始化疫剃,不能成功為nil
strong钉疫,使用的都是同一塊內(nèi)存地址,一個地方改變巢价,全變
copy 不能改變牲阁,但是能夠重新賦值固阁,初始化,但都為不可變
copy:
runtime:
runtime是OC動態(tài)性的基礎城菊,OC動態(tài)性是指確定對象的類型和方法實現(xiàn)是在運行時實現(xiàn)的备燃,可以在運行時動態(tài)的指向別的類,進行消息傳遞和轉發(fā)
可以在程序運行的時候動態(tài)的創(chuàng)建類和對象凌唬,和方法實現(xiàn)
runtime其實就是把編譯期做的決定推遲到運行期并齐,在運行的時候才去檢查對象的所屬類和方法實現(xiàn),利用這一特性在運行時動態(tài)改變對象的類型和方法實現(xiàn)
對象消息轉發(fā)的過程:
0.對象通過isa指針找到他的所屬類(對象內(nèi)只存有一個isa指針客税,目的是減少內(nèi)存况褪,類中也有一個isa指針指向元類,元類中存放類方法霎挟,元類也有繼承關系)
1.去當前類的緩存方法列表中找
2.去當前類的方法別表中找
3.去父類的方法列表中找窝剖,如果沒有,一直找到根類
4.根類再找不到酥夭,走動態(tài)解析(add_method)和消息轉發(fā)(看別的類能否處理這個消息)
5.沒有,拋出錯誤unrecognize selector
如何實現(xiàn)weak變量的自動置為nil功能赐纱?
runtime在注冊和初始化一個類時,當一個屬性被修飾為weak時熬北,會將weak變量指向的地址作為value放入一張Hash表中疙描,將weak變量的作為key。這樣形成一個key-value的鍵值對讶隐,當引用計數(shù)變?yōu)?的時候起胰,系統(tǒng)通過key-value查找指向weak變量的地址,將變量賦值為nil
內(nèi)存5大分區(qū):
1.堆區(qū) 動態(tài)分配內(nèi)存
2.棧區(qū) 系統(tǒng)管理內(nèi)存
3.靜態(tài)區(qū) 已經(jīng)初始化的全局變量和靜態(tài)變量
4.bss段 未初始化的全局變量和靜態(tài)變量
5.代碼區(qū) 程序運行時產(chǎn)生的二進制數(shù)據(jù)
runloop:
處理事件的循環(huán)巫延。狀態(tài):接受消息效五,恢復,處理炉峰,休眠
分類:source畏妖,observe,timer
應用:1.NSThread用runloop實現(xiàn)線程常駐 2.NSTimer 3.imageView推遲顯示
KVO:
觀察者模式的一種實現(xiàn)
原理:在運行時創(chuàng)建監(jiān)聽對象當前類的子類疼阔,并為這個新的子類重寫了被觀察屬性 keyPath 的 setter 方法戒劫。setter 方法負責通知觀察對象屬性的改變,被觀察對象的 isa 指針從指向原來的類婆廊,變?yōu)橹赶蛐陆ǖ淖宇?/p>
數(shù)組add不會觸發(fā)KVO迅细,沒有走set方法
KVC:
鍵值編碼(Key-Value Coding),一個非正式的 Protocol淘邻,使用字符串(鍵)訪問一個對象實例變量的機制茵典。而不是通過調用 Setter、Getter 方法等顯式的存取方式去訪問宾舅。
多用于訪問系統(tǒng)私有屬性统阿,字典和模型的互相轉換
category:
作用:
1.通過分類來為已知的類擴展方法和屬性
2.通過實現(xiàn)分類的 load 方法來實現(xiàn) Method Swizzling
3.將一個類拆分成多個實現(xiàn)文件
不能添加屬性原因:因為在運行期枚尼,對象的內(nèi)存布局已經(jīng)確定,如果添加實例變量就會破壞類的內(nèi)部布局
添加屬性:通過關聯(lián)對象砂吞,實現(xiàn)對象綁定。沒有實例變量(iVar)
load方法可以繼承崎溃。調用子類的load方法之前蜻直,會先調用父類的load方法,分類中l(wèi)oad方法不會覆蓋本類的load方法袁串,先編譯的分類優(yōu)先調用load方法
原理:
1.在編譯時期概而,會將分類中實現(xiàn)的方法生成一個結構體 method_list_t 、將聲明的屬性生成一個結構體 property_list_t 囱修,然后通過這些結構體生成一個結構體 category_t 赎瑰。
2.然后將結構體 category_t 保存下來
3.在運行時期,Runtime 會拿到編譯時期我們保存下來的結構體 category_t
4.然后將結構體 category_t 中的實例方法列表破镰、協(xié)議列表餐曼、屬性列表添加到主類中
5.將結構體 category_t 中的類方法列表、協(xié)議列表添加到主類的 metaClass 中
這里需要注意的是:category_t 中的方法列表是插入到主類的方法列表前面(類似利用鏈表中的 next 指針來進行插入)鲜漩,所以這里 Category 中實現(xiàn)的方法并不會真正的覆蓋掉主類中的方法源譬,只是將 Category 的方法插到方法列表的前面去了。運行時在查找方法的時候是順著方法列表的順序查找的孕似,它只要一找到對應名字的方法踩娘,就會停止查找,這里就會出現(xiàn)覆蓋方法的這種假象了喉祭。
Extension 和 Category 兩種實現(xiàn)模式區(qū)別
Extension 是在編譯時期實現(xiàn)的养渴,Category是在運行時期決定的
自旋鎖和互斥鎖的區(qū)別
自旋鎖會忙等: 所謂忙等,即在訪問被鎖資源時泛烙,調用者線程不會休眠理卑,而是不停循環(huán)在那里,直到被鎖資源釋放鎖胶惰。
互斥鎖會休眠: 所謂休眠傻工,即在訪問被鎖資源時,調用者線程會休眠孵滞,此時cpu可以調度其他線程工作中捆。直到被鎖資源釋放鎖。此時會喚醒休眠線程坊饶。
優(yōu)缺點:
自旋鎖的優(yōu)點在于泄伪,因為自旋鎖不會引起調用者睡眠,所以不會進行線程調度匿级,cpu時間片輪轉等耗時操作蟋滴。所有如果能在很短的時間內(nèi)獲得鎖染厅,自旋鎖的效率遠高于互斥鎖。
缺點在于津函,自旋鎖一直占用CPU肖粮,他在未獲得鎖的情況下,一直運行--自旋尔苦,所以占用著CPU涩馆,如果不能在很短的時 間內(nèi)獲得鎖,這無疑會使CPU效率降低允坚。自旋鎖不能實現(xiàn)遞歸調用魂那。
pthread_mutex 表示互斥鎖〕硐睿互斥鎖可以傳入不同參數(shù)涯雅,實現(xiàn)遞歸鎖pthread_mutex(recursive)。NSLock展运,NSCondition活逆,NSRecursiveLock,NSConditionLock都是內(nèi)部封裝的pthread_mutex拗胜,即都屬于互斥鎖划乖。@synchronized是NSLock的一種封裝,犧牲了效率挤土,簡潔了語法琴庵。
OSSpinLock 表示自旋鎖,從上圖可以看到自旋鎖的效率最高仰美,但是現(xiàn)在的iOS因為優(yōu)先級反轉的問題迷殿,已經(jīng)不安全,所以推薦使用pthread_mutex或者dispatch_semaphore
aotomic為什么是不安全的
存取能保證數(shù)據(jù)完整性咖杂,但是多線程下讀取的數(shù)據(jù)不確定
atomic所說的線程安全只是保證了getter和setter存取方法的線程安全庆寺,并不能保證整個對象是線程安全的
NSTimer:
target可以是weakself,避免循環(huán)引用
intstancetype id區(qū)別
區(qū)別1:
在ARC(Auto Reference Count)環(huán)境下:
instancetype用來在編譯期確定實例的類型,而使用id的話,編譯器不檢查類型, 運行時檢查類型.
在MRC(Manual Reference Count)環(huán)境下:
instancetype和id一樣,不做具體類型檢查
區(qū)別2:
id可以作為方法的參數(shù),但instancetype不可以
instancetype只適用于初始化方法和便利構造器的返回值類型
空指針和野指針
空指針:不指向任何內(nèi)存地址诉字,賦值為0的指針
野指針:指針指向的內(nèi)存地址已經(jīng)被釋放的指針
NULL空指針 nil空對象 NSNull一個值為空的對象
鏈表和數(shù)組區(qū)別:
鏈表和數(shù)組都屬于線性表懦尝,線性表分為順序線性表(數(shù)組)和鏈表,鏈表分為單向鏈表壤圃,雙向鏈表陵霉,循環(huán)鏈表
鏈表是靠指針連接起來的,內(nèi)存是不連續(xù)的伍绳,節(jié)點內(nèi)容是當前節(jié)點信息和下一個節(jié)點的地址,便于刪除和增加元素踊挠,
數(shù)組在內(nèi)存中是連續(xù)的,便于查找和修改
設計模式:
對象創(chuàng)建:
原型:copy對象
工廠方法:使得類的實例化延遲到其子類冲杀。通過不同的工廠生產(chǎn)不同類型的產(chǎn)品效床,且兩個產(chǎn)品類最終返回的是他們的父類
抽象工廠:提供一個創(chuàng)建一系列相關或相互依賴對象的接口睹酌,而無需指定它們具體的類
生成器:將一個復雜對象的構建與它的表現(xiàn)分離,使得同樣的構建過程可以創(chuàng)建不同的表現(xiàn)
單例:保證一個類僅有一個實例剩檀,并提供一個訪問它的全局訪問點
接口類:
適配器:將一個類的接口轉換成客戶希望的另一個接口憋沿,適配器模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。
橋接:將抽象部分與它的實現(xiàn)部分分離沪猴,使它們都可以獨立地變化卤妒。
外觀:為系統(tǒng)中的一組接口提供一個統(tǒng)一的接口。外觀頂一個高層接口字币,讓子系統(tǒng)更易于使用
對象去耦:
中介者:用一個對象來封裝一系列對象的交互方式,中介者使各對象不需要顯示地相互引用共缕,從而使其耦合松散洗出,而且可以獨立地改變它們之間的交互。UINavigationController
觀察者:定義對象間的一種一對多的依賴關系图谷,當一個對象的狀態(tài)發(fā)生改變時翩活,所有依賴于它的對象都得到通知并自動更新肚逸。 KVO
抽象集合:
組合:將對象組合成樹形結構以表示“部分-整體”的層次結構试吁。組合使得用戶對單個對象和組合對象的使用具有一致性
迭代器:提供一種方法順序訪問一個聚合對象中的各個元素灶轰,而又不需要暴露該對象的內(nèi)部表示
行為擴展:
訪問者:
裝飾:動態(tài)地給一個對象添加一些額外的職責嘹裂。就擴展功能來說恢总,裝飾模式相比生成子類更為靈活 category
責任鏈:使多個對象都有機會處理請求粤攒,從而避免請求的發(fā)送者和接受者之間發(fā)生耦合望抽。此模式將這些對象連成一條鏈算途,并沿著這條鏈傳遞請求盔粹,直到有一個對象處理它為止隘梨。 hit-test 事件響應鏈
swift和OC區(qū)別
swift是靜態(tài)語言,元組舷嗡,方法重載轴猎,高階函數(shù),可選值进萄,函數(shù)式編程捻脖,面向協(xié)議編程,更安全
OC動態(tài)語言
swift逃逸閉包和非逃逸閉包
默認非逃逸閉包中鼠,逃逸閉包生命周期比函數(shù)長可婶,為了保證調用self不為nil,所以需要強引用援雇,避免循環(huán)引用
class和struct區(qū)別
struct值類型扰肌,創(chuàng)建更快,占用內(nèi)存空間小熊杨,struct的方法要去修改property的值曙旭,要加上mutating盗舰,class則不需要。
class引用類型桂躏,成員必須初始化钻趋,可繼承
ISO網(wǎng)絡七層模型:物理層,數(shù)據(jù)鏈路層剂习,網(wǎng)絡層蛮位,傳輸層,表示層鳞绕,會話層失仁,應用層
TCP/IP參考模型:物理層,數(shù)據(jù)鏈路層们何,網(wǎng)絡層萄焦,傳輸層,應用層
傳輸層協(xié)議:
TCP:可靠傳輸冤竹,鏈接需要三次握手拂封,斷開需要四次揮手
UDP:不可靠傳輸
HTTP:建立在TCP基礎上的應用層協(xié)議。
報文格式:
請求:
請求行:請求方法鹦蠕,URL,HTTP版本號
請求頭:Host冒签,User-Agent,Content-Type,Content-Length,Accept,Accept-Language,Accept-Encoding,Cookie,Connection(是否長連接)
請求體:GET請求請求體為空
響應:
狀態(tài)行:HTTP版本號,狀態(tài)碼(100臨時響應钟病,200成功萧恕,300重定向,400客戶端錯誤肠阱,500服務端錯誤)
響應頭:Server,Age(響應持續(xù)時間)廊鸥,Set-Cookie,Connection,
響應體
WebSocket 是一種雙向通信協(xié)議辖所。iOS一般用SocketRocket
原生JS交互
JS調原生:
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message;中執(zhí)行
- (void)addScriptMessageHandler:(id <WKScriptMessageHandler>)scriptMessageHandler name:(NSString *)name;
原生調JS:- (void)evaluateJavaScript:(NSString *)javaScriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;
webview請求相機功能
本地通知原理:
多線程通知惰说,接收通知的方法所在線程是由發(fā)送通知的線程決定的。子線程發(fā)送通知接收通知的方法在子線程缘回,如果需要UI操作需要回到主線程
Universal Link:
iOS9推出吆视,域名必須是HTTPS,不用打開瀏覽器直接跳轉應用酥宴,也可用于應用之間的跳轉啦吧,沒安裝應用則打開網(wǎng)頁,只有當前webview的url域名拙寡,與跳轉目標url域名不一致時授滓,Universal Link 才生效。
配置:
1.在域名根目錄下配置json文件,包含APPID和path
2.在蘋果后臺打開Assocaiated Domains功能
3.在XCode中配置Assocaiated Domains域名
音視頻相關:
視頻音頻格式般堆,F(xiàn)Fmpeg
斷點續(xù)傳
快速打包方式:
fastlane
jenkins
編譯器架構:
傳統(tǒng):前端在孝,優(yōu)化器,后端
iOS:前端(Clang)淮摔,LLVM(Bitcode是LLVM編譯器的中間代碼的一種編碼),后端
算法:
二分法
快排
爬樓梯