如何選擇性地連接動態庫

故事背景

沒有平白無故的重構,也沒有平白無故的優化。故事的開始要追溯到咱們的項目加了某個新功能。緩存

在此以前,項目的編譯連接速度算是比較快,加上IDE編譯緩存的做用,不徹底編譯的話,通常在10秒內就能夠看到你修改的代碼的效果。但爲了這項新功能,咱們使用了某個第三方SDK,這個SDK是以framework的形式提供的。今後以後link階段的時間大大加長,大概須要五分鐘。就算改一行代碼,也須要等三分鐘,喝上一杯茶以後才能看到代碼改動的效果,大大影響了開發效率。產品的功能模塊較多,不少其餘模塊的開發者也深受荼毒。網絡

來看一下系統自己的一些framework的大小,系統相冊Photos.framework是115KB,通信錄動態庫AddressBook.framework是111KB,底層網絡處理庫CFNetwork.framework是295KB,等等。而咱們使用的這個SDK,足足有400多MB!!因此連接速度巨慢也就不足爲奇了。下文將用slow.framework表示此SDK。優化

由於這項新功能是重點核心功能,而這個SDK也是咱們調研比較以後最能知足咱們需求的服務提供方,所以去除或者更換SDK都不太現實。ui

兼顧產品需求和開發效率,只能想辦法縮短編譯連接時間。最直觀的想法是,只有真正開發該新功能模塊的纔去link slow.framework,而其餘模塊的開發則不link它,這樣大部分狀況下的修改能夠不受其影響。spa

所以咱們的核心問題就是,如何選擇性地連接動態庫。調試

實踐

選擇性編譯

假設咱們不連接slow.framework了,那麼使用到SDK中的接口的代碼,確定是編譯不過的。所以在考慮怎樣選擇性連接framework以前,須要先修改代碼,使得用到slow.framework的接口的地方都能有選擇地被編譯。code

添加一個Build Configuration,叫Debug_Fastcdn

Paste_Image.png

這個Debug_Fast選項表示不使用slow.framework,爲其添加一個預約義宏,叫DEBUG_FAST Paste_Image.pngblog

原來使用SDK的代碼都修改爲這樣:接口

#ifndef DEBUG_FAST
// use slow.framework
#else
// balabala
#endif複製代碼

這樣只有在定義了DEBUG_FAST以後,咱們就再也不使用slow.framework中的代碼。

選擇性連接

在這個問題上,咱們嘗試過兩種作法。

多scheme多target

具體步驟以下:

  1. 當前的項目只有一個target,能夠duplicate出另外一個target,咱們暫且稱之爲target_fast
  2. 修改target_fast中的Linked Frameworks and Libraries,將該slow.framework移除。
  3. 建立一個scheme,這個scheme對應到的Executable是target_fast,而且對應的Build Configuration是咱們以前添加好的Debug_Fast,咱們稱之爲scheme_fast。

Paste_Image.png

這樣咱們調試的時候,選擇這個scheme_fast,就能夠不連接slow.framework。

多scheme單target

上述的方法已經能夠解決咱們的問題,可是仍有一些反作用:

  • 使用了多個target以後,之後咱們每添加一個新文件,都須要將其加到兩個target中,雖然Xcode會記住你的選擇,但仍是很醜陋。
  • 多個target對於之後的維護並不友好,要改一項配置也須要同步到兩個target中

所以咱們最後採用了另一種作法:多scheme單target,具體步驟以下:

  1. 先將slow.framework從Linked framework中移除
  2. 修改Other Linker Flags,配置Debug和Release -link slow.framework,而Debug_Fast則不連接 Paste_Image.png
  3. 同上建立多個scheme,其中scheme_fast對應到Debug_Fast這個Build Configuration。

這種解決方案更加簡單輕量,對原有項目的入侵也更少,更好維護。

遇到難題不要抱怨,方法總比困難多;解決了問題也不要輕易知足,可能存在更優雅的解決方案。

相關文章
相關標籤/搜索