因為呆了2年的公司資金鏈出了問題巷嚣,導(dǎo)致我3月8號離職喘先,去旅游,去處理家里的事情花費了2個月的時間廷粒,現(xiàn)在5月份才開始找工作窘拯,以下是我面試中遇到的一些問題“泳ィ總的來說涤姊,除了被阿里和酷狗的面試官虐了,其他的面試還是挺順利嗤放。
1.非對稱加密
http://www.reibang.com/p/53b9ffe8fea6 非對象加密 數(shù)字簽名 證書的仔細(xì)解析思喊。
http://www.reibang.com/p/929f10f40c40 RSA SSH 加密。
2.https 解析 比http更安全的原因
http://www.zixiong.org/blog/2018/02/12/https.html
http://www.reibang.com/p/ce2a9bc519f5 iOS 的https適配次酌。
3.app啟動速度的優(yōu)化恨课。
1.延時啟動讀取io的操作.
減少非系統(tǒng)的framework依賴,如果framework 在當(dāng)前 App 支持的所有 iOS 系統(tǒng)版本中都存在則設(shè)為 required岳服,否則設(shè)置為 optional剂公,optional 會有額外檢查合并非系統(tǒng)庫
刪除無用的 class/selector/category
刪除無用的方法調(diào)用、靜態(tài)變量等減少 C++ 虛函數(shù)(減少創(chuàng)建虛函數(shù)表時間)
使用 Swift 的 struct (從而減少符號數(shù)量)
為不需要寫的屬性添加 readonly減少 +load() 方法吊宋,盡量使用 +initialize() 代替使用
dispatch_one() pthread_once() std::once() 代替 C/C++ attribute(constructor)
減少靜態(tài)構(gòu)造函數(shù)
初始化方法中不要使用 dlopen()
https://blog.csdn.net/u011452278/article/details/54966682 今日頭條的優(yōu)化文章
http://www.reibang.com/p/d280feedbca0
4.可變?nèi)菀撞迦肟罩当紳⒃趺崔k?
-(void)insertSaveObject:(id)anObject atIndex:(NSUInteger)index
-(void)setSaveObject:(id)value forKey:(id)key
過濾
http://www.reibang.com/p/96332619f2dd 框架 NullSafe
5.線程同步
1.NSLock
2.NSLock延伸之NSCondition線程通信處理
3.synchronized代碼塊
4.使用GCD 信號量解決資源搶占問題
5.dispatch_barrier_async
6.pthread_mutex_trylock 互斥鎖
http://www.reibang.com/p/40157a10133d
http://www.reibang.com/p/c04343336193
iOS中保證線程安全的幾種方式與性能對比
http://www.reibang.com/p/938d68ed832c
6.代碼安全
1.沙盒文件加密
2..h代碼混淆
http://www.reibang.com/p/3a9952aa9ed2
7.消息轉(zhuǎn)發(fā)的機制
http://www.reibang.com/p/367b2f6b461f VN逃生之路
8.區(qū)分深拷貝與淺拷貝
淺拷貝:指針拷貝纲辽,不增加新的內(nèi)存。只是新增加一個指針指向原來的內(nèi)存區(qū)域璃搜。
深拷貝:內(nèi)容拷貝拖吼,同時拷貝指針和指針指向的內(nèi)存。新增指針指向新增的內(nèi)存腺劣。
拷貝條件:
iOS中并非所有的對象都支持copy和mutableCopy绿贞,只有遵循了NSCopy協(xié)議或者NSMutableCoy協(xié)議的類才行。如果遵循著兩個協(xié)議就必須分別實現(xiàn)copyWithZone和mutableCopyZone方法
拷貝原則:
1.非容器類:像NSString橘原、NSNumber這樣的不能包含其他對象的系統(tǒng)類
不可變對象調(diào)用copy是淺拷貝籍铁;而調(diào)用muablecopy是深拷貝并得到可變對象
可變對象調(diào)用copy和mutablecopy都是深拷貝涡上, 區(qū)別在于copy返回不可變對象,mutablecopy返回可變對象
2.容器類:像NSArray拒名、NSMutableArray等系統(tǒng)類
不可變對象調(diào)用copy是淺拷貝吩愧,而調(diào)用muablecopy是深拷貝并得到可變對象。
可變對象調(diào)用copy和mutablecopy都是深拷貝增显,區(qū)別在于copy返回不可變對象雁佳,mutablecopy返回可變對象
容器類與非容器類的拷貝原則相似,但需要注意的是:所有的容器類的拷貝同云,拷貝后新容器里的元素始終是淺拷貝糖权,其指針都指向原來對象。
3.自定義類:比如我們自定義一個Student類(實現(xiàn)拷貝協(xié)議)
拷貝協(xié)議的具體實現(xiàn)不同炸站,拷貝效果也就不同星澳。在實現(xiàn)的拷貝協(xié)議方法中直接返回對象的self就相當(dāng)于淺拷貝了,但是是如果返回新創(chuàng)建對象就是深拷貝了旱易。
關(guān)于拷貝的可參考鏈接:參考鏈接1 禁偎、參考鏈接2
9.區(qū)別Strong和weak
在網(wǎng)上找個比較形象的列子來方便理解:
想象我們研究的對象是一條狗,狗想要跑掉(被釋放)阀坏。
1.Strong
strong型指針就像是栓住的狗如暖。只要你用牽繩掛住狗,狗就不會跑掉忌堂。如果有5個人牽著一條狗(5個strong型指針指向1個對象)盒至,除非5個牽繩都脫落 ,否著狗是不會跑掉的浸船。
2.Weak
weak型指針就像是一個小孩指著狗喊到:“看妄迁!一只狗在那” 只要狗一直被栓著,小孩就能看到狗李命,(weak指針)會一直指向它登淘。只要狗的牽繩脫落,狗就會跑掉封字,不管有多少小孩在看著它黔州。
總結(jié):只要最后一個strong型指針不再指向?qū)ο螅敲磳ο缶蜁会尫爬眩词惯€有weak型指針指向它流妻。一旦最后一個strong型指針離去 ,這個對象將被釋放笆制,所有剩余的weak型指針都將被清除绅这。
10.區(qū)分MVC與MVVM
MVC弊端:Controller通常負(fù)責(zé)Model和View關(guān)聯(lián),造成View和Model的耦合度高在辆,而且Controller變得龐大復(fù)雜证薇。
MVVM優(yōu)點:
1.低耦合度苔。View可以獨立于Model變化和修改,一個ViewModel可以綁定到不同的View上浑度,當(dāng)View變化的時候Model可以不變寇窑,當(dāng)Model變化的時候View也可以不變。
2.可重用性箩张∷ィ可以把一些視圖的邏輯放在ViewModel里面,讓很多View重用這段視圖邏輯先慷。
3.獨立開發(fā)饮笛。開發(fā)人員可以專注與業(yè)務(wù)邏輯和數(shù)據(jù)的開發(fā)(ViewModel)。設(shè)計人員可以專注于界面(View)的設(shè)計论熙。
4.可測試性缎浇。可以針對ViewModel來對界面(View)進(jìn)行測試
11.區(qū)分類目與擴展
類目:category 為已知的類增加新的方法
1.類目中擴展的方法會被子類繼承
2.增加原有類的方法赴肚,而且是可以增加多個類目將大的功能劃分為小功能。
3.類目中的方法會比原有類中的方法具有更高優(yōu)先級二蓝。所以不能和原有類方法重名否則覆蓋誉券。
4.類目只能添加方法,不能添加變量
擴展:即延展刊愚,一般是在一個類的實現(xiàn)文件中踊跟。給當(dāng)前類添加私有變量和私有方法。添加的方法是必須實現(xiàn)的
12.區(qū)分#include鸥诽、#import和@class
"#include"
一般來說商玫,導(dǎo)入objective-C的頭文件時用#import,導(dǎo)入c/c++頭文件用#include牡借。include相當(dāng)于拷貝文件中的聲明內(nèi)容拳昌,多次使用就會報重復(fù)定義的錯誤。如: class A钠龙,class B都引用了class C炬藤,而class D中又同時引用class A與class B,就會報重復(fù)引用的錯誤碴里。
"#import"
不會產(chǎn)生重復(fù)定義的錯誤沈矿,因為它會做一次判斷,如果已經(jīng)導(dǎo)入就不再導(dǎo)入了
@class
@class僅僅是類的聲明咬腋,告訴編譯器有這么個類羹膳,具體這個類怎么定義一無所知。
@class在編譯的時候根竿,速度更快陵像,解決引用循環(huán)依賴死鎖的問題(類的擴展就珠,代理設(shè)計模式)
@class還可以解決循環(huán)依賴的問題,例如A.h導(dǎo)入了B.h蠢壹,而B.h導(dǎo)入了A.h嗓违,每一個頭文件的編譯都要讓對象先編譯成功才行。這樣的話图贸,在頭文件中一般使用@class來聲明這個名稱是類的名稱蹂季。 而在實現(xiàn)類里面,因為會用到這個引用類的內(nèi)部的實體變量和方法疏日,所以需要使用#import來包含這個被引用類的頭文件偿洁。
注:#import<> 跟 #import””區(qū)別:#import<> 包含iOS框架類庫里的類,#import""包含項目里自定義的類沟优。
13.區(qū)分TCP和UDP
TCP:面向連接涕滋、傳輸可靠(保證數(shù)據(jù)正確性,保證數(shù)據(jù)順序傳輸)挠阁、用于傳輸大量數(shù)據(jù)(流模式)宾肺、速度慢,建立連接需要開銷較多(時間侵俗,系統(tǒng)資源)锨用。
UDP:面向非連接、傳輸不可靠隘谣、用于傳輸少量數(shù)據(jù)(數(shù)據(jù)包模式)增拥、速度快,傳輸?shù)氖菆笪摹?/p>
14.區(qū)分HTTP與Socket
HTTP請求:客戶端主動發(fā)起請求寻歧,服務(wù)器才能給予響應(yīng)掌栅,一次請求完畢后則斷開連接,節(jié)省資源码泛。
Socket:客戶端與服務(wù)器端直接使用socket套接字連接猾封,雙方保持連接通道,都可以主動發(fā)送數(shù)據(jù)弟晚,適合游戲或股票等這種即時性很強的要求忘衍。主要使用的類是CFSockdetRef。
15.區(qū)分KVC和KVO
KVC:值編碼卿城,一種使用字符串標(biāo)識屬性枚钓,間接訪問對象屬性的方法。而不是調(diào)用存取方法瑟押。
KVO:觀察者模式搀捷。通過監(jiān)聽對象的屬性來更新UI或者狀態(tài)
16.區(qū)分MD5和Base64兩種加密
"數(shù)據(jù)加密的基本過程就是對原來為明文的文件或數(shù)據(jù)按某種算法進(jìn)行處理,使其成為不可讀的一段代碼,通常稱為“密文”嫩舟,使其只能在輸入相應(yīng)的密鑰之后才能顯示出本來內(nèi)容氢烘,通過這樣的途徑來達(dá)到保護(hù)數(shù)據(jù)不被非法人竊取、閱讀的目的家厌。 該過程的逆過程為解密播玖,即將該編碼**信息轉(zhuǎn)化為其原來數(shù)據(jù)的過程。"
"加密技術(shù)通常分為兩大類:“對稱式”和“非對稱式”饭于。"
--------以上內(nèi)容摘自百度--------
MD5:嚴(yán)格來說不算加密算法蜀踏,只能說是摘要算法,而且是一種不可逆的摘要算法掰吕。MD5用于生成摘要果覆,并且無法逆破解得到原文。我們常用它驗證數(shù)據(jù)的有效性殖熟,比如局待,在網(wǎng)絡(luò)請求接口中,通過將所有的參數(shù)生成摘要菱属,客戶端和服務(wù)端采用同樣的規(guī)則生成摘要钳榨,驗證數(shù)據(jù)的有效性。
Base64:一種用64個字符來表示任意二進(jìn)制數(shù)據(jù)的編碼方式纽门,嚴(yán)格來說也不算是一種加密重绷。Base64的操作是可逆的,經(jīng)過encode加密膜毁,可以decode得到原文。Base64常用來解決網(wǎng)絡(luò)請求中特殊編碼問題和輕量型的加密(轉(zhuǎn)化為非明文)愤钾。
關(guān)于這兩種技術(shù)是否為加密算法的討論有很多瘟滨,我是這樣理解的:
嚴(yán)格意義上來說,這兩種技術(shù)都不能算是真正的加密算法能颁。但是把明文轉(zhuǎn)化為不可讀的密文杂瘸,這本就算是一種加密。在日常的開發(fā)工作中伙菊,我們經(jīng)常用這兩種方式將一些數(shù)據(jù)轉(zhuǎn)為不可讀密文败玉,因此稱它們叫做加密算法也不為過。至于是否為加密算法只是一種說法而已镜硕,只要理解了其基本原理與用法即可运翼。又或許我們把它們叫作為一種加密方式會好些。
可參考鏈接:
加密算法
Base64編碼原理與應(yīng)用
17.區(qū)分define定義的宏和const定義的常量
define定義宏的指令兴枯,程序在預(yù)處理階段將用#define所定義的內(nèi)容只是進(jìn)行了替換血淌。因此程序運行時,常量表中并沒有用#define所定義的宏,系統(tǒng)并不為它分配內(nèi)存悠夯,而且在編譯時不會檢查數(shù)據(jù)類型癌淮,出錯的概率要大一些。
const定義的常量沦补,在程序運行時是存放在常量表中乳蓄,系統(tǒng)會為它分配內(nèi)存,而且在編譯時會進(jìn)行類型檢查夕膀。
18.區(qū)分id與instancetype
id:萬能指針虚倒,指向任意類型
instancetype:只能作為方法的范圍類型,并且返回的類型是當(dāng)前定義類的類型店诗。
19.區(qū)分通知和代理
同:都用于對象之間的通信
異:代理是一對一通信裹刮。通知可以一對一,也可以一對多
20.區(qū)分methord和selector
selector只是一個方法名庞瘸,而method包含了方法名和方法實現(xiàn)捧弃。
21.區(qū)分isKindOfClass 與isMemberOfClass
isKindOfClass:確定一個對象是否是一個類的成員,或者是派生自該類的成員.
isMemberOfClass:確定一個對象是否是當(dāng)前類的成員.
注:isMemberOfClass不能檢測任何的類都是基于NSObject類這一事實,而isKindOfClass可以擦囊。
22.區(qū)別面向過程和面向?qū)ο?/p>
面向過程:以事件為編程中心违霞,各功能的實現(xiàn)是按照事件的先后順序或者因果關(guān)系來展開的編程的一種思想
面向?qū)ο螅阂詫ο鬄榫幊痰闹行模允录轵?qū)動瞬场,各功能是模塊化的买鸽,彼此之間獨立互不影響的一種編程思想
23、使 系統(tǒng)的某些block api(如UIView的block版本寫動畫時)贯被,是否也考慮引 循環(huán)問題?
系統(tǒng)的某些block api中眼五,UIView的block版本寫動畫時 需要考慮,但也有 些api 需要考慮:
所謂“引 循環(huán)”是指雙向的強引 彤灶,所以那些“單向的強引 ”(block 強引 self ) 沒有問題看幼, 如這些:
[UIView animateWithDuration:duration animations:^{ [self.superview layoutIfNeeded]; }];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{ self.someProperty = xyz; }];
[[NSNotificationCenter defaultCenter] addObserverForName:@"someNotification"
object:nil queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification * notification) { self.someProperty = xyz; }];
這些情況 需要考慮“引 循環(huán)”。
但如果你使 些參數(shù)中可能含有 ivar 的系統(tǒng) api 幌陕,如 GCD 诵姜、 NSNotificationCenter就要 點: 如GCD 內(nèi)部如果引 self, 且 GCD 的 其他參數(shù)是 ivar搏熄,則要考慮到循環(huán)引 :
__weak typeof(self) weakSelf = self; dispatch_group_async(_operationsGroup, _operationsQueue, ^ {
typeof(self) strongSelf = weakSelf; [strongSelf doSomething];
[strongSelf doSomethingElse];
} );
類似的:
__weak typeof(self) weakSelf = self;
_observer = [[NSNotificationCenter defaultCenter] addObserverForName:@"testKey"
object:nil queue:nil
usingBlock:^(NSNotification *note) { typeof(self) strongSelf = weakSelf;
[strongSelf dismissModalViewControllerAnimated:YES]; }];
self --> _observer --> block --> self 顯然這也是 個循環(huán)引 棚唆。
檢測代碼中是否存在循環(huán)引 問題,可使 Facebook 開源的 個檢測 具 FBRetainCycleDetector 心例。
24宵凌、靜態(tài)庫的原 是 么?你有沒有 寫過靜態(tài)編譯庫,遇到 哪些問題?
庫本質(zhì)上講是 種可執(zhí) 的 進(jìn)制格式止后,可以載 內(nèi)存中執(zhí) 摆寄。是程序代碼的集合, 共享代碼的 種 式。 靜態(tài)庫是閉源庫微饥, 公開源代碼逗扒,都是編譯后的 進(jìn)制 件, 具體實現(xiàn)欠橘。 靜態(tài)庫 般都是以 .a 或者 .framework 形式存在矩肩。 靜態(tài)庫編譯的 件 較 ,因為整個函數(shù)庫的數(shù)據(jù)都會被整合到代碼中肃续,這樣的好處 就是編譯后的程序 需要外部的函數(shù)庫 持黍檩, 好的 點就是如果改變靜態(tài)函數(shù)庫, 就需要程序重新編譯始锚。多次使 就有多份冗余拷 刽酱。 使 靜態(tài)庫的好處:模塊化分 合作、可重 、避免少 改動導(dǎo)致 的重復(fù)編譯鏈 接。 般公司都會有核 開發(fā)團(tuán)隊和普通開發(fā)團(tuán)隊及刻,然后公司的核 業(yè)務(wù)由核 開發(fā)團(tuán)隊 寫成靜態(tài)庫然后讓普通開發(fā)團(tuán)隊調(diào) 众眨,這樣就算普通開發(fā)團(tuán)隊離職也帶 公司的核 業(yè)務(wù)代碼崭庸。 般核 開發(fā)團(tuán)隊是 會離職的。 有靜態(tài)庫 然就有動態(tài)庫 。這 所謂的靜態(tài)和動態(tài)是相對編譯期和運 期的。靜態(tài) 庫在程序編譯時會被鏈接到代碼中头谜,程序運 時將 再需要改靜態(tài)庫, 動態(tài)庫在編 譯時 會被鏈接到代碼中鸠澈,只有程序運 時才會被載 柱告,所以 hook 別 程序或者說 做插件都是運 runtime 機制,然后動態(tài)庫注 修改的笑陈。
制作 .a 件時候末荐,要注意 CPU 架構(gòu)的 持,i386新锈、X86_64、 armv7眶熬、armv7s妹笆。 查看可以通過命令 “ lipo -info 靜態(tài)庫名稱” 。模擬 .a 件和真機 .a 件合并可 以通過 "lipo -create 模擬 靜態(tài)庫1名 真機靜態(tài)庫2名 -output 新靜態(tài)庫名稱" 些坑
命名 要太隨意娜氏,畢竟是被別 拿過去 的要能看懂拳缠。 framework中 到 NSClassFromString,但是轉(zhuǎn)換出來的class 直為nil贸弥。解決 法:在主 程的【Other Linker Flags】需要添加參數(shù)【-ObjC]即可窟坐。 如果Xcode找 到框架的頭 件,你可能是忘記將它們聲明為public 。 解決 法: 進(jìn) target的Build Phases 哲鸳,展開Copy Headers項臣疑,把需要public的頭 件從 Project或Private部分拖拽到Public部分。
盡 要 xib 徙菠。由于靜態(tài)框架采 靜態(tài)鏈接讯沈,linker會剔除所有它認(rèn)為 的代碼。 幸的是婿奔,linker 會檢查xib 件缺狠,因此如果類是在xib中引 , 沒有在O-C代碼中 引 萍摊,linker將從最終的可執(zhí) 件中刪除類挤茄。這是linker的問題, 是框架的問題 (當(dāng)你編譯 個靜態(tài)庫時也會發(fā) 這個問題)冰木。蘋果內(nèi)置框架 會發(fā) 這個問題穷劈,因 為他們是運 時動態(tài)加載的,存在于iOS設(shè)備固件中的動態(tài)庫是 可能被刪除的片酝。 有兩個解決的辦法:
1囚衔、 讓框架的最終 戶關(guān)閉linker的優(yōu)化選項,通過在他們的項 的Other Linker Flags中添加-ObjC和-all_load雕沿。
2练湿、 在框架的另 個類中加 個該類的代碼引 。 如审轮,假設(shè)你有個MyTextField類肥哎, 被linker剔除 。假設(shè)你還有 個MyViewController疾渣,它在xib中使 MyTextField篡诽,MyViewController并沒有被剔除。你應(yīng)該這樣做: 在MyTextField中:
+(void)forceLinkerLoad_ {}
在MyViewController中:
+(void)initialize {[MyTextField forceLinkerLoad_];}
他們?nèi)匀恍枰砑?ObjC到linker設(shè)置榴捡,但 需要強制all_load 杈女。 第2種 法需要你多做 點 作,但卻讓最終 戶避免在使 你的框架時關(guān)閉linker優(yōu) 化(關(guān)閉linker優(yōu)化會導(dǎo)致object 件膨脹)吊圾。
25达椰、 動指定autoreleasepool的前提下, 個autorealese對象在 么時刻釋放? ( 如在 個vc的viewDidLoad中創(chuàng)建) 分兩種情況: 動 預(yù)釋放時機项乒、系統(tǒng) 動去釋放啰劲。
- 動 預(yù)釋放時機--指定autoreleasepool 就是所謂的:當(dāng)前作 域 括號結(jié)束時 釋放。
- 系統(tǒng) 動去釋放-- 動指定autoreleasepool
Autorelease對象出 作 域之后檀何,會被添加到最近 次創(chuàng)建的 動釋放池中蝇裤,并會在 當(dāng)前的 runloop 迭代結(jié)束時釋放廷支。
釋放的時機總結(jié)起來,可以 下圖來表示:
從程序啟動到加載完成是 個完整的運 循環(huán)栓辜,然后會停下來恋拍,等待 戶交互, 戶 的每 次交互都會啟動 次運 循環(huán)啃憎,來處 戶所有的點擊事件芝囤、觸摸事件。 我們都知道: 所有 autorelease 的對象辛萍,在出 作 域之后悯姊,會被 動添加到最近創(chuàng) 建的 動釋放池中。
但是如果每次都放進(jìn)應(yīng) 程序的 main.m 中的 autoreleasepool 中贩毕,遲早有被撐滿的 刻悯许。這個過程中必定有 個釋放的動作。何時? 在 次完整的運 循環(huán)結(jié)束之前辉阶,會被銷毀先壕。
那 么時間會創(chuàng)建 動釋放池?
A:運 循環(huán)檢測到事件并啟動后,就會創(chuàng)建 動釋放池谆甜。
B: 線程的 runloop 默認(rèn)是 作垃僚, 法主動創(chuàng)建,必須 動創(chuàng)建规辱。( 展:run loop和線程是緊密相連的谆棺,可以這樣說run loop是為 線程 ,沒有線程罕袋,它就沒有 存在的必要改淑。Run loops是線程的基礎(chǔ)架構(gòu)部分)
C: 定義的 NSOperation 和 NSThread 需要 動創(chuàng)建 動釋放池。 如: 定 義的 NSOperation 類中的 main 法 就必須添加 動釋放池浴讯。否則出 作 域后朵夏, 動釋放對象會因為沒有 動釋放池去處 它, 造成內(nèi)存泄 榆纽。
但對于 blockOperation 和 invocationOperation 這種 默認(rèn)的Operation 仰猖,系統(tǒng)已經(jīng)幫 我們封裝好 , 需要 動創(chuàng)建 動釋放池奈籽。
@autoreleasepool 當(dāng) 動釋放池被銷毀或者耗盡時饥侵,會向 動釋放池中的所有對象發(fā) 送 release 消息,釋放 動釋放池中的所有對象唠摹。 如果在 個vc的viewDidLoad中創(chuàng)建 個 Autorelease對象,那么該對象會在 viewDidAppear 法執(zhí) 前就被銷毀 奉瘤。
26勾拉、OC完整的消息轉(zhuǎn)發(fā)機制+代碼實現(xiàn)【 擊】煮甥。
消息轉(zhuǎn)發(fā)分為兩 階段。第 階段先征詢接收者藕赞,所屬的類成肘,看其是否能動態(tài)添加 法,以處 當(dāng)前這個“未知的選擇 ”斧蜕,這叫做“動態(tài) 法解析”双霍。 第 階段涉及“完整的消息轉(zhuǎn)發(fā)機制(full forwarding mechanism)”如果運 期系統(tǒng) 已經(jīng)執(zhí) 完第 階段,此時批销,運 期系統(tǒng)會請求我接收者以其它 段來處 消息洒闸。可 以細(xì)分兩 步均芽。1. 先查找有沒有replacement receiver進(jìn) 處 丘逸。若 ,2.運 期系 統(tǒng)把Selector相關(guān)信息封裝到NSInvocation對象中掀宋,再給 次機會深纲,若依舊未處 則 讓NSObject調(diào) doNotReconizeSelector: 接收者在每 步中均有機會處 消息,步驟越往后劲妙,處 消息的代價越 湃鹊。最好能在 第 步就處 完,這樣Runtime System可以將 法緩存起來镣奋,第三步除 修改 標(biāo)相 第 步還要創(chuàng)建處 NSInvocation币呵。
27、iOS app啟動如何優(yōu)化?
- 我們可以通過在 Xcode 中 Edit scheme -> Run -> Auguments 將環(huán)境變 DYLD_PRINT_STATISTICS 設(shè)為 1,在控制臺看到main()函數(shù)之前的啟動時間唆途。
- 分解優(yōu)化 標(biāo) 分步達(dá)到優(yōu)化 的 1). 耗時操作異步處
2). 如果啟動流程依賴 絡(luò)請求回來才能繼續(xù),那么需要考慮 絡(luò)極差情況下的啟
動速度
3). 如果APP有l(wèi)oading 告 并且對分辨率的要求較 ,請嘗試做緩存吧
4). 主 Controller中的viewDidLoad和viewWillAppear 法中盡 少做事情 5). 排查清 項 中未使 到的類庫以及Framework
6). 刪減合并 些OC類,刪減沒有 到或者可以 的靜態(tài)變 富雅、 法等
7). 輕 化+load 法中的內(nèi)容,可延遲到+initialize中
28、UITableView性能優(yōu)化肛搬,超實
- Cell重 1.1>數(shù)據(jù)源 法優(yōu)化
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
在可 的 會重復(fù)繪制 没佑,每次刷新顯示都會去創(chuàng)建新的Cell, 常耗費性 能温赔。
解決 案: 先創(chuàng)建 個靜態(tài)變 reuseID(代 法返回Cell會調(diào) 很多次蛤奢,防 重復(fù)創(chuàng)建,static保證只會被創(chuàng)建 次陶贼,提 性能)啤贩,然后,從緩存池中取相應(yīng) identifier的Cell并 新數(shù)據(jù)拜秧,如果沒有痹屹,才開始alloc新的Cell,并 identifier標(biāo)識 Cell枉氮。每個Cell都會注冊 個identifier(重 標(biāo)識符)放 緩存池志衍,當(dāng)需要調(diào) 的時 候就直接從緩存池 找對應(yīng)的id暖庄,當(dāng) 需要時就放 緩存池等待調(diào) 。(移出屏幕的 Cell才會放 緩存池中楼肪,并 會被release)所以在數(shù)據(jù)源 法中做出如下優(yōu)化:
// 調(diào) 次數(shù)太多培廓,static 保證只創(chuàng)建 次reuseID,提 性能
static NSString *reuseID = “reuseCellID”;
// 緩存池中取已經(jīng)創(chuàng)建的cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseID];
1.2>緩存池的實現(xiàn)
當(dāng)Cell要alloc時春叫,UITableView會在堆中開辟 段內(nèi)存以供Cell緩存之 肩钠。Cell的重 通過identifier標(biāo)識 同類型的Cell,由此可以推斷出暂殖,緩存池外層可能是 個可變 字典价匠,通過key來取出內(nèi)部的Cell, 緩存池為存儲 同 度央星、 同類型(包含圖 霞怀、 Label等)的Cell,可以推斷出緩存池的字典內(nèi)部可能是 個可變數(shù)組莉给, 來存放 同 類型的Cell毙石,緩存池中只會保存已經(jīng)被移出屏幕的 同類型的Cell。
1.3>緩存池獲取可重 Cell兩個 法的區(qū)別
-(nullable __kindof UITableViewCell *)dequeueReusableCellWithIdentifier: (NSString *)identifier;
這個 法會查詢可重 Cell颓遏,如果注冊 原型Cell徐矩,能夠查詢到,否則叁幢,返回nil; 且需要判斷if(cell == nil)滤灯,才會創(chuàng)建Cell, 推薦
-(__kindof UITableViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath NS_AVAILABLE_IOS(6_0);
使 這個 法之前曼玩,必須通過xib(storyboard)或是Class(純代碼)注冊可重 Cell鳞骤, 且這個 法 定會返回 個Cell
注冊Cell - (void)registerNib:(nullable UINib *)nib forCellReuseIdentifier:(NSString
*)identifier NS_AVAILABLE_IOS(5_0); - (void)registerClass:(nullable Class)cellClass forCellReuseIdentifier:(NSString *)identifier NS_AVAILABLE_IOS(6_0);
好處:如果緩沖區(qū) Cell 存在,會使 原型 Cell 實 化 個新的 Cell黍判, 需要再判 斷豫尽,同時代碼結(jié)構(gòu) 清晰。
- 定義 種(盡 少)類型的Cell及善 hidden隱藏(顯示)subviews
2.1> 種類型的Cell
分析Cell結(jié)構(gòu)顷帖,盡可能的將 相同內(nèi)容的抽取到 種樣式Cell中美旧,前 已經(jīng)提到
Cell的重 機制,這樣就能保證UITbaleView要顯示多少內(nèi)容贬墩,真正創(chuàng)建出的Cell可能 只 屏幕顯示的Cell多 點榴嗅。雖然Cell的’體積’可能會 點,但是因為Cell的數(shù) 會 很多陶舞,完全可以接受的嗽测。好處:
- 減少代碼 ,減少Nib 件的數(shù) 肿孵,統(tǒng) 個Nib 件定義Cell唠粥,容 修改优炬、維護(hù)
- 基于Cell的重 ,真正運 時鋪滿屏幕所需的Cell數(shù) 致是固定的厅贪,設(shè)為N個。所 以如果如果只有 種Cell雅宾,那就是只有N個Cell的實 ;但是如果有M種Cell养涮,那么運 時最多可能會是“M x N = MN”個Cell的實 ,雖然可能并 會占 太多內(nèi)存眉抬,但是 能少點 是 好嗎贯吓。
2.2>善 hidden隱藏(顯示)subviews
只定義 種Cell,那該如何顯示 同類型的內(nèi)容呢?答案就是蜀变,把所有 同類型的 view都定義好悄谐,放在cell ,通過hidden顯示库北、隱藏爬舰,來顯示 同類型的內(nèi)容。畢 竟寒瓦,在 戶快速滑動中情屹,只是單純的顯示、隱藏subview 實時創(chuàng)建要快得多杂腰。
- 提前計算并緩存Cell的 度 在iOS中垃你, 設(shè)UITableViewCell的預(yù)估 的情況下,會優(yōu)先調(diào)
”tableView:heightForRowAtIndexPath:” 法喂很,獲取每個Cell的即將顯示的 度惜颇, 從 確定UITableView的布局,實際就是要獲取contentSize(UITableView繼承 UIScrollView,只有獲取滾動區(qū)域少辣,才能實現(xiàn)滾動),然后才調(diào) ”tableView:cellForRowAtIndexPath”,獲取每個Cell凌摄,進(jìn) 賦值。如果項 中模塊有 10000個Cell需要顯示毒坛,可想 知...
解決 案:我個 認(rèn)為望伦,可以創(chuàng)建 個frame模型,提前計算每個Cell的 度煎殷。參考 其中 篇博客的時候屯伞,在解決這個問題的時候,可以將計算Cell的 度放 數(shù)據(jù)模 型豪直,但這與MVC設(shè)計模式可能稍微有點沖突劣摇,這個時候我就想到MVVM這種設(shè)計模 式,這個時候才能稍微有點MVVM這種設(shè)計模式的優(yōu)點(其實還是很 解的)弓乙,可 以講計算Cell 度放 ViewModel(視圖模型)中末融,讓Model(數(shù)據(jù)模型)只負(fù)責(zé)處 數(shù)據(jù)钧惧。
4.異步繪制( 定義Cell繪制) 遇到 較復(fù)雜的界 的時候,如復(fù)雜點的圖 混排勾习,上 的那種優(yōu)化 的 式可
能就 能滿 要求 浓瞪,當(dāng)然 ,由于我的開發(fā)經(jīng)驗尚短巧婶,說實話乾颁,還沒遇到要將 定 義的Cell重新繪制
5.滑動時,按需加載 開發(fā)的過程中艺栈, 定義Cell的種類千奇百怪英岭,但Cell本來就是 來顯示數(shù)據(jù)的, 說
100%帶有圖 湿右,也差 多诅妹,這個時候就要考慮,下滑的過程中可能會有點卡頓毅人,尤其 絡(luò) 好的時候吭狡,異步加載圖 是個程序員都會想到,但是如果給每個循環(huán)對象都加 上異步加載丈莺,開啟的線程太多赵刑, 樣會卡頓,我記得好像線程條數(shù) 般3-5條场刑,最多 也就6條吧般此。這個時候 UIScrollViewDelegate兩個代 法就能很好地解決這個問 題。
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate: (BOOL)decelerate
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
6.緩存View
當(dāng)Cell中的部分View是 常獨 的牵现,并且 于重 的铐懊, 且“體積” 常 ,在內(nèi) 存可控的前提下瞎疼,我們完全可以將這些view緩存起來科乎。當(dāng)然也是緩存在模型中。
7.避免 的圖 縮放贼急、顏 漸變等茅茂,盡 顯示“ 剛好合適的圖 資源” 8.避免同步的從 絡(luò)、 件獲取數(shù)據(jù)太抓,Cell內(nèi)實現(xiàn)的內(nèi)容來 web空闲,使 異步加載,緩 存請求結(jié)果
9.渲染
9.1>減少subviews的個數(shù)和層級 控件的層級越深走敌,渲染到屏幕上所需要的計算 就越 ;如多 drawRect繪制
元素碴倾,替代 view顯示 9.2>少 subviews的透明圖層
對于 透明的View,設(shè)置opaque為YES,這樣在繪制該View時跌榔,就 需要考慮 被View覆蓋的其他內(nèi)容(盡 設(shè)置Cell的view為opaque异雁,避免GPU對Cell下 的內(nèi)容 也進(jìn) 繪制)
9.3>避免CALayer特效(shadowPath) 給Cell中View加陰影會引起性能問題,如下 代碼會導(dǎo)致滾動時有明顯的卡頓:
view.layer.shadowColor = color.CGColor; view.layer.shadowOffset = offset; view.layer.shadowOpacity = 1; view.layer.shadowRadius = radius;
29僧须、dispatch_barrier_async的作 是 么?
在并 隊 中纲刀,為 保持某些任務(wù)的順序,需要等待 些任務(wù)完成后才能繼續(xù)進(jìn) 担平, 使 barrier 來等待之前任務(wù)完成柑蛇,避免數(shù)據(jù)競爭等問題。 dispatch_barrier_async 函數(shù)會等待追加到Concurrent Dispatch Queue并 隊 中的操作全部執(zhí) 完之后驱闷, 然后再執(zhí) dispatch_barrier_async 函數(shù)追加的處 ,等 dispatch_barrier_async 追加的處 執(zhí) 結(jié)束之后空免,Concurrent Dispatch Queue才恢復(fù)之前的動作繼續(xù)執(zhí) 空另。
打個 : 如你們公司周末跟團(tuán)旅游, 速休息站上蹋砚,司機說: 家都去上廁所扼菠, 速戰(zhàn)速決,上完廁所就上 速坝咐。超 的公共廁所循榆, 家同時去,程序猿很快就結(jié)束 墨坚,但程序媛就可能會慢 些秧饮,即使你第 個回來,司機也 會出發(fā)泽篮,司機要等待所 有 都回來后盗尸,才能出發(fā)。 dispatch_barrier_async 函數(shù)追加的內(nèi)容就如同 “上完廁 所就上 速”這個動作帽撑。
(注意:使 dispatch_barrier_async 泼各,該函數(shù)只能搭配 定義并 隊 dispatch_queue_t 使 。 能使 : dispatch_get_global_queue 亏拉,否則
dispatch_barrier_async 的作 會和 dispatch_async 的作 模 樣扣蜻。 )
30.NSDictionary 的原理
http://www.reibang.com/p/d4b5542740d5
31.哈希表 鏈表
哈希表(Hash table,也叫散列表)及塘,是根據(jù)關(guān)鍵碼值(Key value)而直接進(jìn)行訪問的數(shù)據(jù)結(jié)構(gòu)莽使。也就是說,它通過把關(guān)鍵碼值映射到表中一個位置來訪問記錄笙僚,以加快查找的速度吮旅。這個映射函數(shù)叫做散列函數(shù),存放記錄的數(shù)組叫做散列表。
哈希表hashtable(key庇勃,value) 就是把Key通過一個固定的算法函數(shù)既所謂的哈希函數(shù)轉(zhuǎn)換成一個整型數(shù)字即哈希值檬嘀,然后就將該數(shù)字對數(shù)組長度進(jìn)行取余,取余結(jié)果就當(dāng)作數(shù)組的下標(biāo)责嚷,將value存儲在以該數(shù)字為下標(biāo)的數(shù)組空間里鸳兽。
而當(dāng)使用哈希表進(jìn)行查詢的時候,就是再次使用哈希函數(shù)將key轉(zhuǎn)換為對應(yīng)的數(shù)組下標(biāo)罕拂,并定位到該空間獲取value揍异,如此一來,就可以充分利用到數(shù)組的定位性能進(jìn)行數(shù)據(jù)定位爆班。
鏈表
鏈?zhǔn)酱鎯Φ木€性表衷掷,簡稱鏈表。鏈表由多個鏈表元素組成柿菩,這些元素稱為節(jié)點戚嗅。結(jié)點之間通過邏輯連接,形成鏈?zhǔn)酱鎯Y(jié)構(gòu)枢舶。存儲結(jié)點的內(nèi)存單元懦胞,可以是連續(xù)的也可以是不連續(xù)的。邏輯連接與物理存儲次序沒有關(guān)系凉泄。
**鏈表分為兩個域: **
值域:用于存放結(jié)點的值
鏈域:用于存放下一個結(jié)點的地址或位置
從內(nèi)存角度出發(fā): 鏈表可分為 靜態(tài)鏈表躏尉、動態(tài)鏈表。
從鏈表存儲方式的角度出發(fā):鏈表可分為 單鏈表后众、雙鏈表胀糜、以及循環(huán)鏈表。
http://www.reibang.com/p/88dfc8f405ab
32.OC中l(wèi)oad方法和initialize方法的異同
http://www.reibang.com/p/a00918b73274
33.查找二維數(shù)組的數(shù)字
OC實現(xiàn)代碼
http://www.reibang.com/p/7d7e63493740
34.block相關(guān)
http://www.reibang.com/p/51d04b7639f1
35.阿里面試問題答案集合
http://www.reibang.com/p/86894804db1c
36.排序算法8種
http://www.reibang.com/p/88962dceaad1
37.谷歌智商題目
https://blog.csdn.net/u010850094/article/details/55518326
38.UIView,UIControl,UIResponder之間的關(guān)系
UIControl->(繼承于)UIView->UIResponder
39.assgin 和weak的區(qū)別蒂誉?
weak 當(dāng)引用的對象被釋放 會把指針置空僚纷。
assgin 不會指針置空。
40.通知NSNotification是同步還是異步拗盒?
同步
http://www.reibang.com/p/c73e22ae23df
41.mrc 和arc的區(qū)別
http://www.reibang.com/p/500d63eb7e89
42.一張圖片的內(nèi)存占用大小是由什么決定的
相片的大小是根據(jù)照片的分辨率來計算的怖竭,分辨率越高則相片體積越大,按家用相片尺寸來計算一般從低至30萬像素(10kb-30kb內(nèi)存),高至800萬(3mb-5mb)不等陡蝇。
圖片是很多個像素(pixel)點組合在一起的.
43.isEqual與hash的區(qū)別.
iOS開發(fā) 之 不要告訴我你真的懂isEqual與hash!
http://www.reibang.com/p/915356e280fc?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation
hash 最好的重寫的方式:
In reality, a simple XOR over the hash values of critical properties is sufficient 99% of the time(對關(guān)鍵屬性的hash值進(jìn)行位或運算作為hash值)
44.直播的時候如何將攝像頭和正在輸入鍵盤的視圖合在一起痊臭?
http://www.reibang.com/p/ba1f79f8f6fa
45.可變集合使用copy修飾會不會有問題?
不管是集合類對象登夫,還是非集合類對象广匙,接收到copy和mutableCopy消息時,都遵循以下準(zhǔn)則:
copy返回imutable對象恼策;所以鸦致,如果對copy返回值使用mutable對象接口就會crash潮剪;
mutableCopy返回mutable對象;
下面將針對非集合類對象和集合類對象的copy和mutableCopy方法進(jìn)行具體的闡述
https://www.zybuluo.com/MicroCai/note/50592
46.@synthesize和@dynamic分別有什么作用分唾?
@property有兩個對應(yīng)的詞抗碰,一個是 @synthesize,一個是 @dynamic绽乔。如果 @synthesize和 @dynamic都沒寫弧蝇,那么默認(rèn)的就是@syntheszie var = _var;
@synthesize 的語義是如果你沒有手動實現(xiàn) setter 方法和 getter 方法,那么編譯器會自動為你加上這兩個方法折砸。
@dynamic 告訴編譯器:屬性的 setter 與 getter 方法由用戶自己實現(xiàn)看疗,不自動生成。(當(dāng)然對于 readonly 的屬性只需提供 getter 即可)睦授。假如一個屬性被聲明為 @dynamic var两芳,然后你沒有提供 @setter方法和 @getter 方法,編譯的時候沒問題去枷,但是當(dāng)程序運行到 instance.var = someVar怖辆,由于缺 setter 方法會導(dǎo)致程序崩潰;或者當(dāng)運行到 someVar = var 時沉填,由于缺 getter 方法同樣會導(dǎo)致崩潰。編譯時沒問題佑笋,運行時才執(zhí)行相應(yīng)的方法翼闹,這就是所謂的動態(tài)綁定。
47.GET和POST的區(qū)別蒋纬?
http://www.reibang.com/p/dd9bde6969c8
48.對象銷毀時間表
// 對象的內(nèi)存銷毀時間表
// http://weibo.com/luohanchenyilong/ (微博@iOS程序犭袁)
// https://github.com/ChenYilong
// 根據(jù) WWDC 2011, Session 322 (36分22秒)中發(fā)布的內(nèi)存銷毀時間表
1. 調(diào)用 -release :引用計數(shù)變?yōu)榱? * 對象正在被銷毀猎荠,生命周期即將結(jié)束.
* 不能再有新的 __weak 弱引用, 否則將指向 nil.
* 調(diào)用 [self dealloc]
2. 子類 調(diào)用 -dealloc
* 繼承關(guān)系中最底層的子類 在調(diào)用 -dealloc
* 如果是 MRC 代碼 則會手動釋放實例變量們(iVars)
* 繼承關(guān)系中每一層的父類 都在調(diào)用 -dealloc
3. NSObject 調(diào) -dealloc
* 只做一件事:調(diào)用 Objective-C runtime 中的 object_dispose() 方法
4. 調(diào)用 object_dispose()
* 為 C++ 的實例變量們(iVars)調(diào)用 destructors
* 為 ARC 狀態(tài)下的 實例變量們(iVars) 調(diào)用 -release
* 解除所有使用 runtime Associate方法關(guān)聯(lián)的對象
* 解除所有 __weak 引用
* 調(diào)用 free()
49.tableview用到什么設(shè)計模式?
享元模式 代理模式
50.weak全解析
http://www.reibang.com/p/95b80ec80008
51.UIView的生命周期
52.APP大部分崩潰類型的處理
http://www.reibang.com/p/f63395599633
53.tcp的粘包處理
https://www.cnblogs.com/kex1n/p/6502002.html
54.離屏渲染
https://blog.csdn.net/zhonggaorong/article/details/52757758
55.數(shù)據(jù)庫表的字段沖突如何解決
1.判斷數(shù)據(jù)庫表的版本號是不是有更新蜀备。
2.有更新先創(chuàng)建了臨時 temp表关摇,再把數(shù)據(jù)導(dǎo)入temp 表。
3.再把以前的表刪除掉碾阁,再把temp名字改回來输虱。
TableView優(yōu)化
http://www.reibang.com/p/2d077da3af94
網(wǎng)絡(luò)優(yōu)化
https://mp.weixin.qq.com/s?__biz=MzA4ODk0NjY4NA==&mid=2701606623&idx=1&sn=91a613963e43d432cf8e01af7e057491&chksm=b4d1fc4c83a6755a757975820dba16c72a4876790d708cab236a8b3387cbcef1619371331665&scene=0&pass_ticket=TR%2BQytj%2Fe3F0LkKmFLneOMMrVCSn0BZVsARKST848l95O0lwRLRGFjl7yJAoRERM#rd
招聘一個靠譜的iOS
http://www.reibang.com/p/a9e4c8914e67