卓同學(xué)昨天寫了一篇文章《4道過(guò)濾菜鳥的iOS面試題》嘱巾。我手癢決定默寫一個(gè)參考答案。后來(lái)發(fā)現(xiàn)不認(rèn)真回答被大家噴成狗诫钓,所以決定積極改造旬昭,重新做人。下面就是修編之后的答案菌湃。
1. struct和class的區(qū)別
swift中问拘,class是引用類型,struct是值類型惧所。值類型在傳遞和賦值時(shí)將進(jìn)行復(fù)制骤坐,而引用類型則只會(huì)使用引用對(duì)象的一個(gè)"指向"。所以他們兩者之間的區(qū)別就是兩個(gè)類型的區(qū)別下愈。
class有這幾個(gè)功能struct沒(méi)有的:
- class可以繼承纽绍,這樣子類可以使用父類的特性和方法
- 類型轉(zhuǎn)換可以在runtime的時(shí)候檢查和解釋一個(gè)實(shí)例的類型
- 可以用deinit來(lái)釋放資源
- 一個(gè)類可以被多次引用
struct也有這樣幾個(gè)優(yōu)勢(shì):
- 結(jié)構(gòu)較小,適用于復(fù)制操作势似,相比于一個(gè)class的實(shí)例被多次引用更加安全拌夏。
- 無(wú)須擔(dān)心內(nèi)存memory leak或者多線程沖突問(wèn)題
順便提一下僧著,array在swift中是用struct實(shí)現(xiàn)的。Apple重寫過(guò)一次array障簿,然后復(fù)制就是深度拷貝了盹愚。猜測(cè)復(fù)制是類似參照那樣,通過(guò)棧上指向堆上位置的指針來(lái)實(shí)現(xiàn)的卷谈。而對(duì)于它的復(fù)制操作杯拐,也是在相對(duì)空間較為寬裕的堆上來(lái)完成的,所以性能上還是不錯(cuò)的世蔗。
下面引用貓神OneV的博客:
var arr = [0,0,0]
var newArr = arr
arr[0] = 1
//Check arr and newArr
arr //[1, 0, 0]
newArr // before beta3:[1, 0, 0], after beta3:[0, 0, 0]
所以可以猜測(cè)其實(shí)在背后 Array和 Dictionary的行為并不是像其他 struct 那樣簡(jiǎn)單的在棧上分配端逼,而是類似參照那樣,通過(guò)棧上指向堆上位置的指針來(lái)實(shí)現(xiàn)的污淋。而對(duì)于它的復(fù)制操作顶滩,也是在相對(duì)空間較為寬裕的堆上來(lái)完成的。當(dāng)然寸爆,現(xiàn)在還無(wú)法(或者說(shuō)很難)拿到最后的匯編碼礁鲁,所以這只是一個(gè)猜測(cè)而已。
補(bǔ)充:
C語(yǔ)言中赁豆,struct與的class的區(qū)別:
struct只是作為一種復(fù)雜數(shù)據(jù)類型定義仅醇,不能用于面向?qū)ο缶幊獭?/p>
C++中,struct和class的區(qū)別:
對(duì)于成員訪問(wèn)權(quán)限以及繼承方式魔种,class中默認(rèn)的是private的析二,而struct中則是public的。class還可以用于表示模板類型节预,struct則不行叶摄。
2. 介紹一下觀察者模式
觀察者模式(Observer Pattern):定義對(duì)象間的一種一對(duì)多依賴關(guān)系,使得每當(dāng)一個(gè)對(duì)象狀態(tài)發(fā)生改變時(shí)安拟,其相關(guān)依賴對(duì)象皆得到通知并被自動(dòng)更新蛤吓。
在IOS中典型的推模型實(shí)現(xiàn)方式為NSNotificationCenter和KVO。
NSNotificationCenter
- 觀察者Observer糠赦,通過(guò)NSNotificationCenter的addObserver:selector:name:object接口來(lái)注冊(cè)對(duì)某一類型通知感興趣会傲。在注冊(cè)時(shí)候一定要注意,NSNotificationCenter不會(huì)對(duì)觀察者進(jìn)行引用計(jì)數(shù)+1的操作拙泽,我們?cè)诔绦蛑嗅尫庞^察者的時(shí)候唆铐,一定要去報(bào)從center中將其注銷了。
- 通知中心NSNotificationCenter奔滑,通知的樞紐艾岂。
- 被觀察的對(duì)象,通過(guò)postNotificationName:object:userInfo:發(fā)送某一類型通知朋其,廣播改變王浴。
- 通知對(duì)象NSNotification脆炎,當(dāng)有通知來(lái)的時(shí)候,Center會(huì)調(diào)用觀察者注冊(cè)的接口來(lái)廣播通知氓辣,同時(shí)傳遞存儲(chǔ)著更改內(nèi)容的NSNotification對(duì)象秒裕。
KVO
KVO的全稱是Key-Value Observer,即鍵值觀察钞啸。是一種沒(méi)有中心樞紐的觀察者模式的實(shí)現(xiàn)方式几蜻。一個(gè)主題對(duì)象管理所有依賴于它的觀察者對(duì)象,并且在自身狀態(tài)發(fā)生改變的時(shí)候主動(dòng)通知觀察者對(duì)象体斩。
- 注冊(cè)觀察者
[object addObserver:self forKeyPath:property options:NSKeyValueObservingOptionNew context:]梭稚。 - 更改主題對(duì)象屬性的值,即觸發(fā)發(fā)送更改的通知絮吵。
- 在制定的回調(diào)函數(shù)中弧烤,處理收到的更改通知。
- 注銷觀察者 [object removeObserver:self forKeyPath:property]蹬敲。
3.在一個(gè)HTTPS連接的網(wǎng)站里暇昂,輸入賬號(hào)密碼點(diǎn)擊登錄后,到服務(wù)器返回這個(gè)請(qǐng)求前伴嗡,中間經(jīng)歷了什么
這個(gè)非常得深非常得廣急波,我來(lái)大概說(shuō)一下。
客戶端打包請(qǐng)求瘪校。包括url幔崖,端口啊,你的賬號(hào)密碼等等渣淤。賬號(hào)密碼登陸應(yīng)該用的是Post方式,所以相關(guān)的用戶信息會(huì)被加載到body里面吉嫩。這個(gè)請(qǐng)求應(yīng)該包含三個(gè)方面:網(wǎng)絡(luò)地址价认,協(xié)議,資源路徑自娩。注意用踩,這里是HTTPS,就是HTTP + SSL / TLS忙迁,在HTTP上又加了一層處理加密信息的模塊(相當(dāng)于是個(gè)鎖)脐彩。這個(gè)過(guò)程相當(dāng)于是客戶端請(qǐng)求鑰匙。
服務(wù)器接受請(qǐng)求姊扔。一般客戶端的請(qǐng)求會(huì)先發(fā)送到DNS服務(wù)器惠奸。 DNS服務(wù)器負(fù)責(zé)將你的網(wǎng)絡(luò)地址解析成IP地址,這個(gè)IP地址對(duì)應(yīng)網(wǎng)上一臺(tái)機(jī)器恰梢。這其中可能發(fā)生Hosts Hijack和ISP failure的問(wèn)題佛南。過(guò)了DNS這一關(guān)梗掰,信息就到了服務(wù)器端,此時(shí)客戶端會(huì)和服務(wù)器的端口之間建立一個(gè)socket連接嗅回,socket一般都是以file descriptor的方式解析請(qǐng)求及穗。這個(gè)過(guò)程相當(dāng)于是服務(wù)器端分析是否要向客戶端發(fā)送鑰匙模板。
服務(wù)器端返回?cái)?shù)字證書绵载。服務(wù)器端會(huì)有一套數(shù)字證書(相當(dāng)于是個(gè)鑰匙模板)埂陆,這個(gè)證書會(huì)先發(fā)送給客戶端。這個(gè)過(guò)程相當(dāng)于是服務(wù)器端向客戶端發(fā)送鑰匙模板娃豹。
客戶端生成加密信息焚虱。根據(jù)收到的數(shù)字證書(鑰匙模板),客戶端會(huì)生成鑰匙培愁,并把內(nèi)容鎖上著摔,此時(shí)信息已經(jīng)加密。這個(gè)過(guò)程相當(dāng)于客戶端生成鑰匙并鎖上請(qǐng)求定续。
客戶端發(fā)送加密信息谍咆。服務(wù)器端會(huì)收到由自己發(fā)送出去的數(shù)字證書加鎖的信息。 這個(gè)時(shí)候生成的鑰匙也一并被發(fā)送到服務(wù)器端私股。這個(gè)過(guò)程是相當(dāng)于客戶端發(fā)送請(qǐng)求摹察。
服務(wù)器端解鎖加密信息。服務(wù)器端收到加密信息后倡鲸,會(huì)根據(jù)得到的鑰匙進(jìn)行解密供嚎,并把要返回的數(shù)據(jù)進(jìn)行對(duì)稱加密。這個(gè)過(guò)程相當(dāng)于服務(wù)器端解鎖請(qǐng)求峭状、生成克滴、加鎖回應(yīng)信息。
服務(wù)器端向客戶端返回信息优床∪芭猓客戶端會(huì)收到相應(yīng)的加密信息。這個(gè)過(guò)程相當(dāng)于服務(wù)器端向客戶端發(fā)送回應(yīng)胆敞。
客戶端解鎖返回信息着帽。客戶端會(huì)用剛剛生成的鑰匙進(jìn)行解密移层,將內(nèi)容顯示在瀏覽器上仍翰。
HTTPS加密過(guò)程詳解請(qǐng)去https原理:證書傳遞、驗(yàn)證和數(shù)據(jù)加密观话、解密過(guò)程解析
4.在一個(gè)app中間有一個(gè)button予借,在你手觸摸屏幕點(diǎn)擊后,到這個(gè)button收到點(diǎn)擊事件,中間發(fā)生了什么
響應(yīng)鏈大概有以下幾個(gè)步驟
- 設(shè)備將touch到的UITouch和UIEvent對(duì)象打包, 放到當(dāng)前活動(dòng)的Application的事件隊(duì)列中
- 單例的UIApplication會(huì)從事件隊(duì)列中取出觸摸事件并傳遞給單例UIWindow
- UIWindow使用hitTest:withEvent:方法查找touch操作的所在的視圖view
RunLoop這邊我大概講一下
- 主線程的RunLoop被喚醒
- 通知Observer蕾羊,處理Timer和Source 0
- Springboard接受touch event之后轉(zhuǎn)給App進(jìn)程中
- RunLoop處理Source 1喧笔,Source1 就會(huì)觸發(fā)回調(diào),并調(diào)用_UIApplicationHandleEventQueue() 進(jìn)行應(yīng)用內(nèi)部的分發(fā)龟再。
- RunLoop處理完畢進(jìn)入睡眠书闸,此前會(huì)釋放舊的autorelease pool并新建一個(gè)autorelease pool
深挖請(qǐng)去深入理解RunLoop
UIResponder是UIView的父類,UIView是UIControl的父類利凑。
聲明一下浆劲,第3題依然有很大缺陷,不過(guò)因?yàn)樯钔诘牡胤教喟С海疚牟豢赡芡耆骖櫯平瑁荒軖伌u引玉。另外文章的目的是以面試題為引進(jìn)行學(xué)習(xí)割按,所以寫得有點(diǎn)多膨报,可能與面試技巧和時(shí)間有沖突。