Swift — 面試題挑戰賽(1)

讓我們一起來討論以及研究一些 iOS 面試題目吧。

Jeremy Xue
Jeremy Xue ‘s Blog
7 min readMay 27, 2019

--

Photo by Daniel McCullough on Unsplash

# 前言

剛好上一梯 iOS-Camp 學員差不多到了要出去面試找工作的時期,而這段時間可能就需要複習以及科普一些常會碰到的面試題目,於是工作室的 Mentor Don Chen 提議要不要大家一起過一遍 iOS 的面試題目。

我想我裡面也有許多不太清楚的知識,需要找時間來惡補這些理論(實作派QQ),所以我決定參加這一次的面試題挑戰賽。遇到會的就當複習,不會的就需要找時間再一次深入研究囉。

開船啦 🚢

面試題目在下方,有興趣的朋友也可以跟我們一起過這些 iOS 的面試題。

# 本期題目:

— Swift:

  1. What is an in-out parameter?
  2. Lazy Stored Property vs Stored Property
  3. Fileprivate and Private access level

#What is an in-out parameter?

個人是覺得用 reference 的概念來理解 in-out 參數,蠻簡單易懂的 😎

默認情況下,函數的參數通常為常數。如果嘗試從函數體中去改變函數參數的值時會導致編譯錯誤。這意味著你無法錯誤的改變參數的值。

如果希望函數修改參數的值,並且你想要函數調用結束後這些更改依然存在,那麼請將該參數定義為輸入輸出參數(in-out parameter)。

你只能將變數作為 in-out 參數的參數傳遞。你不能傳遞常數或是文字值作為參數,因為不能修改常數跟文字值。當你將變數名稱作為參數傳遞給輸入輸出參數時,可以在變數名稱前面放置 & 符號,標示他可以由函數修改。

下面示範一個常見數字交換的範例:

可以發現當我們執行完 swapTwoInt 後, a、b 兩者的值交換了,即使它們兩者定義在該函數體外。該函數首先將 a 的值存到一個臨時的常數 temporaryA中,接著將 b 的值賦給 a,b 接收 a 原有的值,也就是 temporaryA

你可以用兩個 Int 類型的變數來調用swapTwoInts。需要注意的是,someIntanotherInt在傳入swapTwoInts函數前,都加了&的前綴。

其他補充:

In-out 參數的傳遞過程如下:

  1. 當調用該 function 時,將複製該參數的值。
  2. 在函數體內,該副本被修改。
  3. 當該 function 返回時,其副本的值將分配給原始的參數。

這個行為被稱為 copy-in copy-outcall by value result。例如:當計算屬性或具有 Observer 的屬性作為 in-out 參數傳遞時,其 getter 作為函數調用的一部份被調用,其setter作為函數返回的一部分被調用。

作為優化,當參數是存儲在記憶體中實體位址的值,在函數體內部和外部使用相同的記憶體位置,其優化的行為稱為 call by reference,它滿足了所有 copy-in copy-out 的所有要求,同時也除去了複製的開銷。使用 copy-in copy-out 給定的模型編寫程式碼,而不依賴於 call-by-reference 優化,以便在有或沒有優化的情況下它都能正常運作。

想更深入了解 in-out 參數,可以查看這篇官方文件中的 In-Out Parameters

# Lazy Stored Property vs Stored Property

這邊存儲屬性的部分就不多解釋,就單純解釋 Lazy 的部分

延遲存儲屬性(Lazy Stored Property)是一個屬性,其初始值在第一次使用時之前不會計算。透過在宣告前編寫一個 lazy 修飾符來表示為延遲存儲的屬性。

當初始值依賴於外部因素時,延遲屬性非常有用,這些外部因素的值在實例初始化完成之後才知道。當屬性的初始值需要複雜計算成本高的設置時,延遲屬性也很有用,除非需要,否則不應執行該設置

舉個例子來說,當你有個需要大量的計算成本的屬性,並且不一定會訪問或修改該屬性時,使用 lazy 修飾符宣告為延遲存儲屬性很有用。延遲存儲屬性只有在第一次被使用時的時候才會被初始化,之後會一直存在

# Fileprivate and Private access level

Swift 為程式碼中的實體提供了五種不同的訪問級別。這些訪問級別與定義實體的 source file 相關,也與 source file 所屬的 module 相關。

這邊我們就只討論 file-private 跟 private 兩個訪問級別:

  • File-private 訪問將實體的使用限制在其自己的 source file 中。當在整個文件中使用這些細節時,使用 file-private 訪問來隱藏特定功能的實現細節。
  • Private 訪問將實體的使用限制為封閉宣告以及同一個文件中該宣告的擴展。當這些細節只有在一個宣告中使用時,使用 private 訪問來隱藏特定的實現細節。

宣告這些訪問級別時,內部的訪問級別不能高於外部的訪問級別,例如 class 宣告被為 private 訪問級別,其內部的內容就不能被設置為 open

想深入了解訪問級別 Access Control 可以查看這篇官方文件。

--

--

Jeremy Xue
Jeremy Xue ‘s Blog

Hi, I’m Jeremy. [好想工作室 — iOS Developer]