本文是「iOS 面試之道」勘誤系列的第二篇。
Swift 初始化方法描述的漏洞
書中 105 頁的描述是:Swift 初始化方法必須保證所有非 Optional
的成員變數都完成初始化。
這個表述是不嚴謹的。
Swift 初始化方法必須保證:
- 所有非 lazy /非 Optional 的可變 stored property
- 所有非 computed 不可變 stored property
都完成初始化。其中 stored property 的對義語是 computed property。
也就是說下列程式碼是不能被成功編譯的,因為 bar
雖然是 Optional
的,但是確實一個不可變成員變數:
class Foo {
let bar: String?
init() {
}
}
複製程式碼
但是下列程式碼又是可以被成功編譯的:
class Foo {
let bar: String = {
return "Bar"
}
init() {
}
}
複製程式碼
因為上述程式碼的 bar
是一個 computed property,而不是 stored property。
如果你覺得上述描述實在太難記,那麼只需要記憶以下內容:Swift 會強制所有不可變變數以及可變變數中非 optional 的在變數生命週期的「產生」階段都被初始化。這個「產生」階段對於 class
和 struct
的 properties 而言就是 init
函式,對於全域性變數和函式體內的本地變數而言就是變數宣告的時候。
Swift 和 Objective-C 的自省描述有問題
書中 109 頁:
... 這兩個方法(
[NSObject -isKindOfClass:]
和[NSObject -isMemberOfClass:]
)的使用有一個前提,既obj
必須是NSObject
或其子類。
這個表述是有問題的,-isKindOfClass:
和 -isMemberOfClass:
是定義在 NSObject
這個 protocol 之中的,只要遵從 (conformed to) 了這個 protocol 那麼你就可以使用這兩個方法來進行自省,比如說 NSProxy
及其子類。
實際上 Objective-C runtime 也提供一組 API 來完成類似的功能,只是這組 API 中有些有可以不檢查 class hierarchy。你如果構建過用來擴充套件 Objective-C 執行時的框架,那麼你應該會很熟悉。
iOS 動畫實現方式記錄不完全
iOS 動畫還包括 CADisplayLink
驅動的動畫,比較有名的使用這個類來驅動動畫的 iOS UI 元件就有 LTMorphingLabel。另外有很多遊戲或者三維程式也是用這個類來驅動的。
同時 UIScrollView
也是 iOS 上動畫的重要來源,而且用這玩意兒做動畫比較考驗智力水平。基本上每年蘋果都會在 WWDC 開專門的 sessions 講如何使用 UIScrollView
及其子類。
Plist 檔案介紹不完全
Plist 在早期還有二進位制檔案的實現。詳情請看這篇文章。