以下是回顧之前上荠列、中、下三篇底層面試題的補充载城,附上答案肌似。
俗話說得好,底層不牢个曙,地動山搖锈嫩。
這些答案只是給大家一些參考受楼,大家可以再結(jié)合自己理解進行回答垦搬,有需要的朋友們下面來一起看看吧。
本文收錄:公眾號【iOS進階寶典《iOS底層面試干貨分享(補充)》】
iOS開發(fā)中的加密方式
iOS加密相關(guān)算法框架:CommonCrypto
艳汽。
1:對稱加密: DES猴贰、3DES、AES
- 加密和解密使用同一個密鑰河狐。
- 加密解密過程:
明文->密鑰加密->密文
米绕,密文->密鑰解密->明文
瑟捣。
- 優(yōu)點:算法公開、計算量少栅干、加密速度快迈套、加密效率高、適合大批量數(shù)據(jù)加密碱鳞;
- 缺點:雙方使用相同的密鑰桑李,密鑰傳輸?shù)倪^程不安全,易被破解窿给,因此為了保密其密鑰需要經(jīng)常更換贵白。
AES:AES又稱高級加密標準,是下一代的加密算法標準崩泡,支持128禁荒、192、256位密鑰的加密角撞,加密和解密的密鑰都是同一個呛伴。iOS一般使用ECB模式,16字節(jié)128位密鑰谒所。
AES算法主要包括三個方面:輪變化磷蜀、圈數(shù)和密鑰擴展。
- 優(yōu)點:高性能百炬、高效率褐隆、靈活易用、安全級別高剖踊。
- 缺點:加密與解密的密鑰相同庶弃,所以前后端利用AES進行加密的話,如何安全保存密鑰就成了一個問題德澈。
DES:數(shù)據(jù)加密標準歇攻,DES算法的入口參數(shù)有三個:Key
、Data
梆造、Mode
缴守。
- 其中Key為7個字節(jié)共56位,是DES算法的工作密鑰镇辉;Data為8個字節(jié)64位屡穗,是要被加密或被解密的數(shù)據(jù);Mode為DES的工作方式忽肛,有兩種:加密村砂、解密。
- 缺點:與AES相比屹逛,安全性較低础废。
3DES:3DES是DES加密算法的一種模式汛骂,它使用3條64位的密鑰對數(shù)據(jù)進行三次加密。是DES向AES過渡的加密算法评腺,是DES的一個更安全的變形帘瞭。它以DES為基本模塊,通過組合分組方法設(shè)計出分組加密算法蒿讥。
2.非對稱加密:RSA加密
- 非對稱加密算法需要成對出現(xiàn)的兩個密鑰图张,公開密鑰(
publickey
) 和私有密鑰(privatekey
) 。- 加密解密過程:對于一個私鑰诈悍,有且只有一個與之對應(yīng)的公鑰祸轮。生成者負責生成私鑰和公鑰,并保存私鑰侥钳,公開公鑰适袜。
公鑰加密,私鑰解密舷夺;或者私鑰數(shù)字簽名苦酱,公鑰驗證。公鑰和私鑰是成對的给猾,它們互相解密疫萤。
特點:
1).對信息保密,防止中間人攻擊:將明文通過接收人的公鑰加密敢伸,傳輸給接收人扯饶,因為只有接收人擁有對應(yīng)的私鑰,別人不可能擁有或者不可能通過公鑰推算出私鑰池颈,所以傳輸過程中無法被中間人截獲尾序。只有擁有私鑰的接收人才能閱讀。此方法通常用于交換對稱密鑰躯砰。
2). 身份驗證和防止篡改:權(quán)限狗用自己的私鑰加密一段授權(quán)明文每币,并將授權(quán)明文和加密后的密文,以及公鑰一并發(fā)送出來琢歇,接收方只需要通過公鑰將密文解密后與授權(quán)明文對比是否一致兰怠,就可以判斷明文在中途是否被篡改過。此方法用于數(shù)字簽名李茫。
- 優(yōu)點:加密強度小揭保,加密時間長,常用于數(shù)字簽名和加密密鑰涌矢、安全性非常高掖举、解決了對稱加密保存密鑰的安全問題。
- 缺點:加密解密速度遠慢于對稱加密娜庇,不適合大批量數(shù)據(jù)加密塔次。
3. 哈希算法加密:MD5加密
、.SHA加密
名秀、HMAC加密
- 哈希算法加密是通過哈希算法對數(shù)據(jù)加密励负,加密后的結(jié)果不可逆,即加密后不能再解密匕得。
- 特點:不可逆继榆、算法公開、相同數(shù)據(jù)加密結(jié)果一致汁掠。
- 作用:信息摘要略吨,信息“指紋”,用來做數(shù)據(jù)識別的考阱。如:用戶密碼加密翠忠、文件校驗、數(shù)字簽名乞榨、鑒權(quán)協(xié)議秽之。
MD5加密:對不同的數(shù)據(jù)加密的結(jié)果都是定長的32位字符。
.SHA加密:安全哈希算法吃既,主要適用于數(shù)字簽名標準(DSS
)里面定義的數(shù)字簽名算法(DSA)考榨。對于長度小于2^64
位的消息,SHA1
會產(chǎn)生一個160位的消息摘要鹦倚。當接收到消息的時候河质,這個消息摘要可以用來驗證數(shù)據(jù)的完整性。在傳輸?shù)倪^程中震叙,數(shù)據(jù)很可能會發(fā)生變化愤诱,那么這時候就會產(chǎn)生不同的消息摘要。當然除了SHA1
還有SHA256
以及SHA512
等捐友。
HMAC加密:給定一個密鑰淫半,對明文加密,做兩次“散列”匣砖,得到的結(jié)果還是32位字符串科吭。
4. Base64加密
- 一種編碼方式,嚴格意義上來說不算加密算法猴鲫。其作用就是將二進制數(shù)據(jù)編碼成文本对人,方便網(wǎng)絡(luò)傳輸。
- 用
base64
編碼之后拂共,數(shù)據(jù)長度會變大牺弄,增加了大約 1/3,但是好處是編碼后的數(shù)據(jù)可以直接在郵件和網(wǎng)頁中顯示宜狐;
- 雖然
base64
可以作為加密势告,但是base64
能夠逆運算蛇捌,非常不安全!- base64 編碼有個非常顯著的特點咱台,末尾有個 ‘=’ 號络拌。
- 原理:
1). 將所有字符轉(zhuǎn)化為ASCII碼;
2). 將ASCII碼轉(zhuǎn)化為8位二進制回溺;
3). 將二進制三位一組不足補0春贸,共24位,再拆分成6位一組共四組遗遵;
4). 統(tǒng)一在6位二進制前補兩個0到八位萍恕;
5). 將補0后的二進制轉(zhuǎn)為十進制;
6). 最后從Base64編碼表獲取十進制對應(yīng)的Base64編碼车要。
App安全允粤,數(shù)字簽名,App簽名屯蹦,重簽名
因為應(yīng)用實際上是一個加殼的ipa文件维哈,但是有可能被砸殼甚至越獄手機下載的ipa包直接就是脫殼的,可以直接反編譯登澜,所以不要在plist文件
阔挠、項目中的靜態(tài)文件
中存儲關(guān)鍵的信息。所以敏感信息對稱加密存儲或者就存儲到keychain
里脑蠕。而且加密密鑰也要定期更換购撼。
數(shù)字簽名是通過HASH算法
和RSA加密
來實現(xiàn)的。 我們將明文數(shù)據(jù)加上通過RSA加密
的數(shù)據(jù)HASH值
一起傳輸給對方谴仙,對方可以解密拿出HASH值
來進行驗證迂求。這個通過RSA加密HASH值
數(shù)據(jù),我們稱之為數(shù)字簽名晃跺。
App簽名
- 1.在Mac開發(fā)機器上生成一對公鑰和私鑰揩局,這里稱為公鑰L,私鑰L(L:Local)掀虎。
- 2.蘋果自己有固定的一對公鑰和私鑰凌盯,私鑰在蘋果后臺,公鑰在每個iOS設(shè)備上烹玉。這里稱為公鑰A驰怎,私鑰A(A:Apple)。
- 3.把開發(fā)機器上的公鑰L傳到蘋果后臺二打,用蘋果后臺的私鑰A去簽名公鑰L县忌。得到一個包含公鑰L以及其簽名數(shù)據(jù)證書。
- 4.在蘋果后臺申請AppID,配置好設(shè)備ID列表和APP可使用的權(quán)限症杏,再加上第③步的證書装获,組成的數(shù)據(jù)用私鑰A簽名,把數(shù)據(jù)和簽名一起組成一個
Provisioning Profile
描述文件鸳慈,下載到本地Mac開發(fā)機器饱溢。
- 5.在開發(fā)時喧伞,編譯完一個APP后走芋,用本地的私鑰L對這個APP進行簽名,同時把第④步得到的
Provisioning Profile
描述文件打包進APP里潘鲫,文件名為embedded.mobileprovision
翁逞,把 APP安裝到手機上。- 6.在安裝時溉仑,iOS系統(tǒng)取得證書挖函,通過系統(tǒng)內(nèi)置的公鑰A,去驗證
embedded.mobileprovision
的數(shù)字簽名是否正確浊竟,里面的證書簽名也會再驗一遍怨喘。
- 7.確保了
embedded.mobileprovision
里的數(shù)據(jù)都是蘋果授權(quán)的以后,就可以取出里面的數(shù)據(jù)振定,做各種驗證必怜,包括用公鑰 L 驗證APP簽名,驗證設(shè)備 ID 是否在 ID 列表上后频,AppID 是否對應(yīng)得上梳庆,權(quán)限開關(guān)是否跟 APP 里的 Entitlements 對應(yīng)等。
OC數(shù)據(jù)類型
① 基本數(shù)據(jù)類型
C語言基本數(shù)據(jù)類型(如
short卑惜、int膏执、float
等)在OC中都不是對象,只是一定字節(jié)的內(nèi)存空間用于存儲數(shù)值露久,他們都不具備對象的特性更米,沒有屬性方法可以被調(diào)用。OC中的基本數(shù)據(jù)類型:
NSInteger
(相當于long型整數(shù))毫痕、
NSUInteger
(相當于unsigned long型整數(shù))征峦、
CGFloat
(在64位系統(tǒng)相當于double,32位系統(tǒng)相當于float)等镇草。
他們并不是類眶痰,只是用typedef
對基本數(shù)據(jù)類型進行了重定義,他們依然只是基本數(shù)據(jù)類型
梯啤。枚舉類型:其本質(zhì)是無符號整數(shù)竖伯。
BOOL類型:是宏定義,OC底層是使用signed char來代表BOOL。
② 指針數(shù)據(jù)類型
指針數(shù)據(jù)類型包括: 類class
七婴、id
祟偷。
- 類class:
NSString
、NSSet
打厘、NSArray
修肠、NSMutableArray
、NSDictionary
户盯、NSMutableDictionary
嵌施、NSValue
、NSNumber(繼承NSValue)
等莽鸭,都是class吗伤,創(chuàng)建后便是對象,繼承NSObject硫眨。
OC中提供了NSValue
足淆、NSNumber
來封裝C語言的基本類型,這樣我們就可以讓他們具有面向?qū)ο蟮奶卣髁恕?/li>
- id:
id
是指向Objective-C對象的指針礁阁,等價于C語言中的void*
巧号,可以映射任何對象指針指向他,或者映射它指向其他的對象姥闭。常見的id類型就是類的delegate屬性丹鸿。
集合NSSet和數(shù)組NSArray區(qū)別:
- 都是存儲不同的對象的地址;
- 但是NSArray是有序的集合泣栈,NSSet是無序的集合卜高,它們倆可以互相轉(zhuǎn)換。
- NSSet會自動刪除重復(fù)元素南片。
- 集合是一種哈希表掺涛,運用散列算法,查找集合中的元素比數(shù)組速度更快疼进,但是它沒有順序薪缆。
③ 構(gòu)造類型
構(gòu)造類型包括:結(jié)構(gòu)體、聯(lián)合體
- 結(jié)構(gòu)體:
struct
伞广,將多個基本數(shù)據(jù)類型的變量組合成一個整體拣帽。結(jié)構(gòu)體中訪問內(nèi)部成員用點運算符訪問。- 聯(lián)合體(共用體):
union
嚼锄,有些類似結(jié)構(gòu)體struct
的一種數(shù)據(jù)結(jié)構(gòu)减拭,聯(lián)合體(union
)和結(jié)構(gòu)體(struct
)同樣可以包含很多種數(shù)據(jù)類型和變量。
結(jié)構(gòu)體和聯(lián)合體的區(qū)別:
- 結(jié)構(gòu)體(
struct
)中所有變量是“共存”的区丑,同一時刻每個成員都有值拧粪,其sizeof
為所以成員的和修陡。
優(yōu)點: 是“有容乃大”,全面可霎;
缺點: 是struct內(nèi)存空間的分配是粗放的魄鸦,不管用不用,全
分配癣朗,會造成內(nèi)存浪費拾因。
- 聯(lián)合體(
union
)中各變量是“互斥”的,同一時刻只有一個成員有值旷余,其sizeof
為最長成員的sizeof
绢记。
優(yōu)點: 是內(nèi)存使用更為精細靈活,也節(jié)省了內(nèi)存空間荣暮。
缺點: 就是不夠“包容”庭惜,修改其中一個成員時會覆蓋原來的成員值罩驻;
property和屬性修飾符
@property的本質(zhì)是 ivar(實例變量)
+ setter
+ getter
.
我們每次增加一個屬性時內(nèi)部都做了什么:
- 1.系統(tǒng)都會在
ivar_list
中添加一個成員變量的描述穗酥;- 2.在
method_list
中增加setter
與getter
方法的描述;- 3.在屬性列表中增加一個屬性的描述惠遏;
- 4.然后計算該屬性在對象中的偏移量砾跃;
- 5.給出
setter
與getter
方法對應(yīng)的實現(xiàn),在setter
方法中從偏移量的位置開始賦值节吮,在getter
方法中從偏移量開始取值抽高,為了能夠讀取正確字節(jié)數(shù),系統(tǒng)對象偏移量的指針類型進行了類型強轉(zhuǎn)。
修飾符:
- MRC下:
assign、retain鲤妥、copy构蹬、readwrite、readonly种远、nonatomic、atomic
等。- ARC下:
assign莹桅、strong、weak烛亦、copy诈泼、readwrite、readonly煤禽、nonatomic铐达、atomic、nonnull檬果、nullable瓮孙、null_resettable贾节、_Null_unspecified
等。
下面分別解釋
assign
:用于基本數(shù)據(jù)類型衷畦,不更改引用計數(shù)栗涂。如果修飾對象(對象在堆需手動釋放內(nèi)存,基本數(shù)據(jù)類型在棧系統(tǒng)自動釋放內(nèi)存)祈争,會導(dǎo)致對象釋放后指針不置為nil 出現(xiàn)野指針斤程。retain
:和strong一樣,釋放舊對象菩混,傳入的新對象引用計數(shù)+1忿墅;在MRC中和release成對出現(xiàn)。strong
:在ARC中使用沮峡,告訴系統(tǒng)把這個對象保留在堆上疚脐,直到?jīng)]有指針指向,并且ARC下不需要擔心引用計數(shù)問題邢疙,系統(tǒng)會自動釋放棍弄。weak
:在被強引用之前,盡可能的保留疟游,不改變引用計數(shù)呼畸;weak引用是弱引用,你并沒有持有它颁虐;它本質(zhì)上是分配一個不被持有的屬性蛮原,當引用者被銷毀(dealloc)時,weak引用的指針會自動被置為nil另绩。
可以避免循環(huán)引用儒陨。copy
:一般用來修飾不可變類型屬性字段,如:NSString
笋籽、NSArray
蹦漠、NSDictionary
等。用copy修飾可以防止本對象屬性受外界影響干签,在NSMutableString
賦值給NSString
時津辩,修改前者 會導(dǎo)致 后者的值跟著變化。還有block
也經(jīng)常使用 copy 修飾符容劳,但是其實在ARC中編譯器會自動對block進行copy操作喘沿,和strong的效果是一樣的。但是在MRC中方法內(nèi)部的block是在棧區(qū)竭贩,使用copy可以把它放到堆區(qū)蚜印。readwrite
:可以讀、寫留量;編譯器會自動生成setter/getter方法窄赋。readonly
:只讀哟冬;會告訴編譯器不用自動生成setter方法。屬性不能被賦值忆绰。nonatomic
:非原子性訪問浩峡。用nonatomic意味著可以多線程訪問變量,會導(dǎo)致讀寫線程不安全错敢。但是會提高執(zhí)行性能翰灾。atomic
:原子性訪問。編譯器會自動生成互斥鎖稚茅,對 setter 和 getter 方法進行加鎖來保證屬性的 賦值和取值 原子性操作是線程安全的纸淮,但不包括可變屬性的操作和訪問。比如我們對數(shù)組進行操作亚享,給數(shù)組添加對象或者移除對象咽块,是不在atomic的負責范圍之內(nèi)的,所以給被atomic修飾的數(shù)組添加對象或者移除對象是沒辦法保證線程安全的欺税。原子性訪問的缺點是會消耗性能導(dǎo)致執(zhí)行效率慢侈沪。nonnull
:設(shè)置屬性或方法參數(shù)不能為空,專門用來修飾指針的魄衅,不能用于基本數(shù)據(jù)類型峭竣。nullable
:設(shè)置屬性或方法參數(shù)可以為空。null_resettable
:設(shè)置屬性晃虫,get方法不能返回為空,set方法可以賦值為空扣墩。_Null_unspecified
:設(shè)置屬性或方法參數(shù)不確定是否為空哲银。
后四個屬性應(yīng)該主要就是為了提高開發(fā)規(guī)范,提示使用的人應(yīng)該傳什么樣的值呻惕,如果違反了對規(guī)范值的要求荆责,就會有警告。
weak修飾的對象釋放則自動被置為nil的實現(xiàn)原理:
Runtime
維護了一個weak表
亚脆,存儲指向某個對象的所有weak指針
做院。weak表
其實是一個hash(哈希)表
,Key
是所指對象的地址濒持,Value
是weak
指針的地址數(shù)組(這個地址的值是所指對象的地址)键耕。
weak 的實現(xiàn)原理可以概括一下三步:
- 1、初始化時:
runtime
會調(diào)用objc_initWeak
函數(shù)柑营,初始化一個新的weak指針指向?qū)ο蟮牡刂贰?/li>- 2屈雄、添加引用時:
objc_initWeak
函數(shù)會調(diào)用objc_storeWeak()
函數(shù),objc_storeWeak()
的作用是更新指針指向官套,創(chuàng)建對應(yīng)的弱引用表酒奶。- 3蚁孔、釋放時,調(diào)用
clearDeallocating
函數(shù)惋嚎。clearDeallocating
函數(shù)首先根據(jù)對象地址獲取所有weak
指針地址的數(shù)組杠氢,然后遍歷這個數(shù)組把其中的數(shù)據(jù)設(shè)為nil
,最后把這個entry從weak表中刪除另伍,最后清理對象的記錄修然。
成員變量ivar
和屬性property
的區(qū)別,以及不同關(guān)鍵字的作用
成員變量: 成員變量的默認修飾符是@protected
质况、不會自動生成set和get方法愕宋,需要手動實現(xiàn)、不能使用點語法調(diào)用结榄,因為沒有set和get方法中贝,只能使用->
。
屬性: 屬性會默認生成帶下劃線的成員變量和setter/getter
方法臼朗、可以用點語法調(diào)用邻寿,實際調(diào)用的是set和get方法。
注意:分類中添加的屬性是不會自動生成 **setter/getter**
方法的视哑,必須要手動添加绣否。
實例變量: class類進行實例化出來的對象為實例對象
關(guān)鍵字作用:
- 訪問范圍關(guān)鍵字
@public
:聲明公共實例變量,在任何地方都能直接訪問對象的成員變量挡毅。@private
:聲明私有實例變量蒜撮,只能在當前類的對象方法中直接訪問,子類要訪問需要調(diào)用父類的get/set方法跪呈。@protected
:可以在當前類及其子類對象方法中直接訪問(系統(tǒng)默認)段磨。@package
:在同一個包下就可以直接訪問,比如說在同一個框架耗绿。- 關(guān)鍵字
@property
:聲明屬性苹支,自動生成一個以下劃線開頭的成員變量_propertyName(默認用@private修飾)、屬性setter误阻、getter方法的聲明债蜜、屬性setter、getter方法的實現(xiàn)究反。注意:在協(xié)議@protocol
中只會生成getter和setter方法的聲明寻定,所以不僅需要手動實現(xiàn)getter和setter方法還需要手動定義變量。@sythesize
:修改@property自動生成的_propertyName成員變量名奴紧,@synthesize propertyName = newName特姐;
。@dynamic
:告訴編譯器:屬性的 setter 與 getter 方法由用戶自己實現(xiàn)黍氮,不自動生成唐含。謹慎使用:如果對屬性賦值取值可以編譯成功浅浮,但運行會造成程序崩潰,這就是常說的動態(tài)綁定捷枯。@interface
:聲明類@implementation
:類的實現(xiàn)@selecter
:創(chuàng)建一個SEL滚秩,類成員指針@protocol
:聲明協(xié)議@autoreleasepool
:ARC中的自動釋放池@end
:類結(jié)束
類簇
類簇是Foundation框架中廣泛使用的設(shè)計模式。類簇在公共抽象超類下對多個私有的具體子類進行分組淮捆。以這種方式對類進行分組簡化了面向?qū)ο罂蚣艿墓部梢婓w系結(jié)構(gòu)郁油,而不會降低其功能豐富度。類簇是基于抽象工廠設(shè)計模式的攀痊。
常見的類簇有 NSString
桐腌、NSArray
、NSDictionary
等苟径。 以數(shù)組為例:不管創(chuàng)建的是可變還是不可變的數(shù)組案站,在alloc
之后得到的類都是 __NSPlaceholderArray
。而當我們 init
一個不可變的空數(shù)組之后棘街,得到的是__NSArray0
蟆盐;如果有且只有一個元素,那就是 __NSSingleObjectArrayI
遭殉;有多個元素的石挂,叫做 __NSArrayI
;init
出來一個可變數(shù)組的話险污,都是 __NSArrayM
痹愚。
優(yōu)點:
- 可以將抽象基類背后的復(fù)雜細節(jié)隱藏起來。
- 程序員不會需要記住各種創(chuàng)建對象的具體類實現(xiàn)罗心,簡化了開發(fā)成本里伯,提高了開發(fā)效率。
- 便于進行封裝和組件化渤闷。
- 減少了 if-else 這樣缺乏擴展性的代碼。
- 增加新功能支持不影響其他代碼脖镀。
缺點:
- 已有的類簇非常不好擴展飒箭。
我們運用類簇的場景:
- 出現(xiàn) bug 時,可以通過崩潰報告中的類簇關(guān)鍵字蜒灰,快速定位 bug 位置弦蹂。
- 在實現(xiàn)一些固定且并不需要經(jīng)常修改的事物時,可以高效的選擇類簇去實現(xiàn)强窖。例:
- 針對不同版本凸椿,不同機型往往需要不同的設(shè)置,這時可以選擇使用類簇翅溺。
- app 的設(shè)置頁面這種并不需要經(jīng)常修改的頁面脑漫,可以使用類簇去創(chuàng)建大量重復(fù)的布局代碼髓抑。
文末推薦:iOS熱門文集&視頻解析
① Swift
② iOS底層技術(shù)
③ iOS逆向防護
④ iOS面試合集
⑤ 大廠面試題+底層技術(shù)+逆向安防+Swift
喜歡的小伙伴記得點贊喔~
收藏等于白嫖,點贊才是真情?( ′???` )?