# 2020/7/9 Cocoaheads Zonble 講述 * 在 Objc 裡的 Category 包成 SDK 的時候,在 Swift 看不到是為什麼? * 要在 Xcode build setting 加上 -objc 才會把 Category 包進去 * NSNumber 繼承自什麼? * NSValue * 為什麼 NSInteger 不能放到 NSArray 去?(這題請涵宇回答,Challenge from Shiva) * 因為 NSInteger 不是 Object,NSArray 只能放 Object。(NSInteger 沒有 *) * 什麼是 header search paths? * 編譯 C, Objective-C, C++ 或 Objective-C++ 時要讓編譯器搜尋需要被 import 的 header 檔清單 * 在早期開發時,Library 只會發佈 .a 檔及多個 header,此時需要加入 `LIBRARY_SEARCH_PATHS` 與 `HEADER_SEARCH_PATHS`,讓 IDE 知道需要額外搜尋的目錄 * 另外,在 macOS App 可能會用到如 /usr/local 或是 /AppleInternal/Library 內的 dyld, bin 檔或 Framework,如果沒有在 `LD_RUNPATH_SEARCH_PATHS` 加入搜尋目標,在軟體啟動時會馬上報 Image not found 的 crash * 選用 Objc 當 SDK 的開發語言,主要是能穩定又安全的讓 Objc/Swift 呼叫。因為 Swift 的 Struct 無法被 Objc 呼叫。我們無法決定客戶要用 Objc 甚至是哪一版的 Swfit。因此採用 Objc 是最好的。 * 什麼是 linker?(題目記不清楚) * [wiki]https://en.wikipedia.org/wiki/Linker_(computing) * ![](https://i.imgur.com/bUgVnTt.png) * Nil/nil/NSNull 差別在哪? * Nil 跟 nil 都是指向一位空的記憶體位置,而 Nil 是指 Class 的空,nil 是指 instance 的空 * 記憶體位置在哪? * 記憶體位置在 0 * NSNull 是 JSON 裡面的 nil value 呈現的方式 * NULL 是在 C header 裡的 define [SO](https://stackoverflow.com/a/12024299/10172299) * 除了 Nil/nil/NSNull 之外還有什麼方式可以表達沒有值? * 專屬 WebKit 使用的 `WebUndefined` (https://developer.apple.com/documentation/webkit/webundefined) * Javascript Value 轉換成為 iOS Type 對照表(https://developer.apple.com/documentation/javascriptcore/jsvalue) * AVFoundation 的底層有一些是用 WebKit 實作的,有多少不確定 * WebKit 是 Open source 的專案,從第一台 iPhone 就有了。 * NSString *text = @"hello";, "hello" 的 retain count 是多少? * Retain count 的最大值(應該是 NSNotFound) https://developer.apple.com/documentation/foundation/nsnotfound * Objc 在編譯階段會把所有的 literal 編好放在某個位置,因為是程式碼區段,不會被釋放,可是因為是 NSObject,必然還是要有 Retain count, 所以被設定為 NSNotFound(2^64-1) * NSString *text = @"\0"; 會發生什麼事?文字長度是多少? * 1。 * 一堆 queue 跟 thread 的討論 * Thread 可以自己 New. 但是如果沒有事情可以做的時候,就會被關閉,沒有要被關閉的話,就要跑一個 loop. * 決定 Queue 要在哪一個 Thread 上面執行,是 Queue 本身,Queue 本身被賦予任務時,會開一個 Thread 去執行,或者找一個 Thread 去執行. * iOS 裡面可以指定 Selector 到某一個 Thread 去執行(https://developer.apple.com/documentation/objectivec/nsobject/1414476-perform?fbclid=IwAR2iayOHYiXnsHYdNsyyJgYmKH6ppF72JDdpkfw75ItegM1qm5oKu4aUO9M) * 延續上一條,由參數 wait 決定是 sync 還是 async 的模式. (感謝 Lin li 提供) * 在 Objc 使用 get 開頭的 method 是指要拿 C 層級的資料,這是 Objc 的 convention。Objc 自己的 getter 不會用 get 開頭。 * Swift Optimization Level 有哪幾種優化等級?差別在哪? * Optimization Level: None [-Onone] * Optimization Level: Fast [-O] * Optimization Level: Fast,WMO [-O -whole module optimization] * 編譯器會把一些常數直接加起來,或是把一些泛型做客製的處理。Fast 就是只專注一個檔案的優化。而 Fast,WMO 是把全部專案的 swift 放在同一個 file 再去優化。 * -Osize > 這邊的 optimization 看起來已經變預設值了,現在在 clang 和 Swift compiler 則有不同的 opimization 選項。 > ![](https://i.imgur.com/FtyVGMx.png) > > Whole-module optimization can be enabled with the -whole-module-optimization (or -wmo) compiler flag, and in Xcode 8 it is turned on by default for new projects. > https://swift.org/blog/whole-module-optimizations/ > https://swift.org/blog/osize/ * Swift 的 Void 真實身分是什麼? * 是空的 tuple (https://developer.apple.com/documentation/swift/void) * 跟 C 的 void 不一樣,void FUNCTION(), void* POINTER 也不一樣 * Objc 的 static variable 存在哪裡? * 只存在這個 class。 * Objc 的 Block 能不能放進 NSArray? * 可以,因為 Block 是物件。 * Objc 的 Block 能不能寫遞迴? * 不行,會 crash * 因為 block 執行完成之前,變數尚未被賦值,是 nil, 呼叫會 Crash. * 下面這段可以執行??? (請涵宇研究 😜) ``` int(^__block test)(int) = ^int(int i) { if (i < 1) { return -1; } else if (i <= 2) { return 1; } return test(i - 1) + test(i - 2); }; for (int i = 1; i < 10; i++) { printf("%i ", test(i)); } ``` * Swift 的 closure 能不能寫遞迴? ```swift // 可以執行的方式 var worker = {} var count = 1 worker = { print(count) count += 1 if count > 10 {return} worker() } worker() // 不能執行的版本 let worker = { worker() // Compile error: Variable used within its own initial value } ``` * DataSource 跟 Delegate 最關鍵的差異是什麼? * DataSource 的 method 裡面不能呼叫 reloadData,不然會無限迴圈。 * tableView(_:heightForRowAt:) 是 UITableViewDelegate 的 method。(https://developer.apple.com/documentation/uikit/uitableviewdelegate/1614998-tableview)