iOS面試題分享(一)

這是我參與8月更文挑戰的第10天,活動詳情查看: 8月更文挑戰sql

dSYM你是如何分析的?

dSYM是什麼?

Xcode編譯項目以後,咱們會看到一個同名的dSYM文件,dSYM是保存十六進制函數地址映射信息的中轉文件,咱們調試的symbols都會包含在這個文件中,而且每次編譯項目的時候都會生成一個新的dSYM文件,位於/User/<用戶名>/Library/Developer/Xcode/Archives目錄下,對於每個發佈版本咱們都頗有必要保存對應的Archives文件;數據庫

dSYM文件有什麼用?

當咱們軟件release模式打包或上線後,不會像咱們在Xcode中那樣直觀的看到用崩潰的錯誤,這個時候咱們就須要分析crash report文件了,iOS設備中會有日誌文件保存咱們每一個應用出錯的函數內存地址,經過XcodeOrganizer能夠將iOS設備中的DeviceLog導出成crash文件,這個時候咱們就能夠經過出錯的函數地址去查詢dSYM文件中程序對應的函數名和文件名。大前提是咱們須要有軟件版本對應的dSYM文件,這也是爲何咱們頗有必要保存每一個發佈版本的Archives文件了。編程

如何將文件一一對應?

每個xx.appxx.app.dSYM文件都有對應的UUID, crash文件也有本身的UUID,只要這三個文件的UUID-致,咱們就能夠經過他們解析出正確的錯誤函數信息了。api

  • 1.查看xx.app文件的UUID, terminal 中輸入命令: dwarfdump --uuid xx.app/xx (xx表明你的項目名)
  • 2.查看xx.app.dSYM文件的UUID,在terminal中輸入命令: dwarfdump --uuid xx.app.dSYM
  • 3.crash文件內第一行Incident Identifier就是該crash文件的UUID

多線程有哪幾種?

多線程分類

  • pthread
    • 一套通用的多線程API
    • 適用於Unix\Linux\Windows等系統
    • 跨平臺,可移植
    • 使用難度大
    • 使用語言:C語言
    • 使用頻率:幾乎不使用
    • 線程生命週期:開發者進行管理
  • NSThread
    • 面向對象
    • 簡單易用,可直接操做線程
    • 使用語言:OC語言
    • 使用頻率:偶爾使用
    • 線程生命週期:開發者進行管理
  • GCD
    • 替換NSThread的技術
    • 充分利用了設備的多核(自動)
    • 使用語言:C語言
    • 使用頻率:常用
    • 線程生命週期:自動管理
  • NSOperation
    • 基於GCD
    • 比GCD多了一些更簡單實用的功能
    • 使用更加面向對象
    • 使用語言:OC語言
    • 使用頻率:常用
    • 線程生命週期:自動管理

多線程的原理

同一時間,CPU只能處理1條線程,只有1條線程在工做(執行)多線程併發(同時)執行,實際上是CPU快速地在多條線程之間調度(切換)若是CPU調度線程的時間足夠快,就形成了多線程併發執行的 假象思考:若是線程很是很是多,會發生什麼狀況?CPU會在N多線程之間調度,CPU會累死,消耗大量的CPU資源每條線程被調度執行的頻次會下降(線程的執行效率下降)markdown

多線程的優勢

能適當提升程序的執行效率能適當提升資源利用率(CPU、內存利用率)網絡

多線程的缺點

線程須要佔用必定的內存空間(默認狀況下,主線程佔用1M,子線程佔用512KB),若是開啓大量的線程,會佔用大量的內存空間,下降程序的性能線程越多,CPU在調度線程上的開銷就越大程序設計更加複雜:好比線程之間的通訊、多線程的數據共享;數據結構

GCD與NSOperation的比較

  • 一、GCD是底層的C語言構成的API,而NSOperationQueue及相關對象是Objc的對象。在GCD中,在隊列中執行的是由block構成的任務,這是一個輕量級的數據結構;而Operation做爲一個對象,爲咱們提供了更多的選擇;
  • 二、在NSOperationQueue中,咱們能夠隨時取消已經設定要準備執行的任務(固然,已經開始的任務就沒法阻止了),而GCD無法中止已經加入queueblock(實際上是有的,但須要許多複雜的代碼);
  • 三、NSOperation可以方便地設置依賴關係,咱們可讓一個Operation依賴於另外一個Operation,這樣的話儘管兩個Operation處於同-個並行隊列中,但前者會直到後者執行完畢後再執行;
  • 四、咱們能將KVO應用在NSOperation中,能夠監聽一個Operation是否完成或取消,這樣子能比GCD更加有效地掌控咱們執行的後臺任務;
  • 五、在NSOperation中,咱們可以設置NSOperationpriority優先級,可以使同一個並行隊列中的任務區分前後地執行,而在GCD中,咱們只能區分不一樣任務隊列的優先級,若是要區分block任務的優先級,也須要大量的複雜代碼;
  • 六、咱們可以對NSOperation進行繼承,在這之,上添加成員變量與成員方法,提升整個代碼的複用度,這比簡單地將block任務排入執行隊列更有自由度,可以在其之.上添加更多自定製的功能。總的來講,Operation queue提供了更多你在編寫多線程程序時須要的功能,並隱藏了許多線程調度,線程取消與線程優先級的複雜代碼,爲咱們提供簡單的API入口。從編程原則來講,-般咱們須要儘量的使用高等級、封裝完美的API,在必須時才使用底層API。可是我認爲當咱們的需求可以以更簡單的底層代碼完成的時候,簡潔的GCD或許是個更好的選擇,而Operation queue爲咱們提供能更多的選擇。
  • 七、NSOperation擁有更多的函數可用,具體查看api。NSOperationQueue是在GCD基礎.上實現的,只不過是GCD更高一層的抽象
  • 八、在NSOperationQueue中,能夠創建各個NSOperation之間的依賴關係。
  • 九、NSOperationQueue支持KVO。能夠監測operation是否正在執行(isExecuted)、是否結束(isFinished) , 是否取消(isCanceld)
  • 十、GCD只支持FIFO的隊列,而NSOperationQueue能夠調整隊列的執行順序(經過調整權重)。NSOperationQueue能夠方便的管理併發、NSOperation之間的優先級。
  • 總結
    • 使用NSOperation的狀況:各個操做之間有依賴關係、操做須要取消暫停、併發管理、控制操做之間優先級,限制同時能執行的線程數量.讓線程在某時刻中止/繼續等。
    • 使用GCD的狀況:通常的需求很簡單的多線程操做,用GCD均可以了,簡單高效。從編程原則來講,通常咱們須要儘量的使用高等級、封裝完美的API,在必須時才使用底層API。當需求簡單,簡潔的GCD或許是個更好的選擇,而Operation queue爲咱們提供能更多的選擇。

單例的弊端

  • 優勢:
    • 一個類只被實例化一次,提供了對惟一實例的受控訪問
    • 節省系統資源
    • 容許可變數目的實例
  • 缺點:
    • 一個類只有一個對象,可能形成責任太重,在必定程度上違背了單一職責原則
    • 因爲單例模式中沒有抽象層,所以單例類的擴展有很大困難
    • 濫用單例將帶來一些負面問題,如:爲了節省資源將數據庫鏈接池對象設計爲單例類,可能會致使共享鏈接池對象的程序過多而出現鏈接池溢出;若是實例化的對象長時間不被利用,系統會認爲是垃圾而被回收,這將致使對象狀態的丟失

介紹下App啓動的完成過程

App啓動過程

  • 解析Info.plist
  • 加載相關信息,例如閃屏
  • 沙盒創建、權限檢查
  • Mach-O加載
  • 若是是二進制文件,尋找合適當前CPU類別的部分
  • 加載全部依賴的Mach-O文件(遞歸調用Mach-o加載方法)
  • 定位內部、外部指針引用,例如字符串,函數等
  • 執行聲明爲attribute(constructor)的C函數
  • 加載類的擴展中的方法
  • C++靜態對象加載,調用Objc+load函數

程序執行

  • main函數
  • 執行UlApplicationMain函數
  • 建立UIApplication對象
  • 建立UIApplicationDelegate對象並複製
  • 讀取配置文件info.plist,設置程序啓動的一些屬性
  • 建立應用程序的Main Runloop循環
  • UlApplicationDelegate對象開始處理監聽事件
  • 程序啓動以後,首先調用application.didFinishLaunchingWithOptions:方法
  • 果info.plist中配置了啓動的storyBoard的文件名,則加載storyboard文件
  • 若是沒有配置,則根據代碼建立UIWindow ->rootViewController->顯示

App啓動過慢,多是哪些因素引發的?

  • 影響啓動性能的因素App啓動過程當中每一個步驟都會影響啓動性能,可是有些部分所消耗的時間少之又少,另外有些部分根本沒法避免,考慮到投入產出比,咱們只列出咱們能夠優化的部分: main(函數以前耗時的影響因素
  • 動態庫加載越多,啓動越慢。
  • ObjC類越多,啓動越慢
  • Cconstructor函數越多,啓動越慢
  • C++靜態對象越多,啓動越慢
  • ObjC+load越多,啓動越慢實驗證實,在ObjC類的數目 同樣多的狀況下,須要加載的動態庫越多,App啓動就越慢。一樣的,在動態庫同樣多的狀況下,ObjC的類越多,App的啓動也越慢。須要加載的動態庫從1個上升到10個的時候,用戶幾乎感知不到任何分別,但從10個, 上升到100個的時候就會變得十分明顯。同理,100個類和1000個類, 可能也很難查察以爲出,但1000個類和10000個類的分別就開始明顯起來。一樣的,儘可能不要寫atribute((constrcror))C函數,也儘可能不要用到C++的靜態對象;至於ObjC+load方法,彷佛你們已經習慣不用它了。任何狀況下,能用dispatch_ _once()來完成的,就儘可能不要用到以上的方法。main()函數以後耗時的影響因素
  • 執行main()函數的耗時
  • 執行applicationWillFinishLaunching的耗時
  • rootViewController及其childViewController的加載、view及其subviews的加載applicationWillFinishLaunching的耗時

0x8badf00d表示什麼?

  • 0x8badf00d:該編碼表示應用是由於發生watchdog超時而被iOS終止的。一般是應用花費太多時間而沒法啓動、終止或響應用系統事件。
  • 0xbad22222:該編碼表示VolP應用由於過於頻繁重啓而被終止
  • Oxdead10cc: 該代碼代表應用由於在後臺運行時佔用系統資源,如通信錄數據庫不釋放而被終止。
  • Oxdeadfa11:該代碼表示應用是被用戶強制退出的。根據蘋果文檔,強制退出發生在用戶長按開關按鈕直到出現「滑動來關機」,而後長按Home按鈕。強制退出將產生包含0xdeadfa11異常編碼的崩潰日誌,由於大多數是強制退出是由於應用阻塞了界面。

怎麼防止反編譯?

  • 本地數據加密: iOS應用防反編譯加密技術之一:對NSUserDefaults,sqlite存儲文件數據加密,保護賬號和關鍵信息
  • URL編碼加密: iOS應用防反編譯加密技術之二:對程序中出現的URL進行編碼加密,防此URL被靜態分析
  • 網絡傳輸數據加密: iOS應用防反編譯加密技術之三:對客戶端傳輸數據提供加密方案,有效防止經過網絡接口的攔截獲取數據
  • 方法體,方法名高級混淆: iOS應用防反編譯加密技術之四:對應用程序的方法名方法體進行混淆,保證源碼被逆向後沒法解析代碼
  • 程序結構混排加密: iOS應用防反編譯加密技術之五:對應用程序邏輯結構進行打亂混排,保證源碼可讀性降到最低
  • 藉助第三方APP加固

你瞭解哪些第三方原理或者底層知識?

RuntimeRunloopblockSDWebImageAFNYYCacheGCD等等底層實現多線程

相關文章
相關標籤/搜索