iOS開發之版本控制以及去除過期警告

weixin_34320159發表於2017-07-21

開門見山,版本控制有以下兩種時機:

  • 預編譯
  • 執行時

預編譯

在編譯之前使用預編譯指令來判斷當前裝置版本,不同版本執行不同的方法以便達到版本控制的目的。(iOS預編譯指令)

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_5_0
    // This code will compile on versions >= ios5.0
    //這裡面的程式碼在iOS5.0版本以上包括5.0才會編譯
#else
    // This code will compile on versions<5.0
    //這裡面的程式碼在iOS5.0版本以下才會編譯
#endif

或者使用以下也OK

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
    //xcode baseSDK為7.0或者以上
#else
    //xcode baseSDK為7.0以下的
#endif

這是iOS定義了這個巨集所以我們可以直接拿來做判斷,後面只要把5改成相應的版本就行了。

執行時

執行的時候我們一般會用下面的這種方式獲取系統版本來判斷:

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
   //裝置系統為IOS 7.0或者以上的
}else{
   //裝置系統為IOS 7.0以下的
}

也可以用以下的方式:

if (@available(iOS 9.0, *)) {
     // Fallback on this or after versions
} else {
     // Fallback on earlier versions
}


過期警告:
當我們在使用API的過程中難免會碰到一些過期的API,那編譯器在編譯的時候就會報警告,即便你做了版本控制,但還是會有很煩人的警告出現,那怎麼消除這種過期的API警告呢?

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
        //此處寫你過期API相關的程式碼
#pragma clang diagnostic pop

這樣警告就消失了,那麼也就不會那麼煩心了,作為一個強迫症的我,很有必要!



擴充套件一:真機和模擬器巨集

真機和模擬器的使用場景:
我們有時候會用到真機除錯,比如說:用到攝像頭.但是很多情況下我們不需要用真機,只需要模擬器就OK,所以為了避免在開發的過程中不會因為某些部分需要真機的功能而導致程式崩潰,我們就需要做真機和模擬器判斷而執行不同程式碼。

蘋果關於真機和模擬器有兩個巨集定義

  • TARGET_IPHONE_SIMULATOR
  • TARGET_OS_IPHONE

在真機sdk中位於iOS->usr/include/targetconditionals.h中,
在模擬器sdk中位於simulator->usr/include/targetconditionals.h中

仔細看其模擬器sdk中的定義:

#define TARGET_OS_IPHONE            1     
#define TARGET_IPHONE_SIMULATOR     1 

再來看真機sdk中的定義:

#define TARGET_OS_IPHONE            1     
#define TARGET_IPHONE_SIMULATOR     0 

可以發現兩者的區別僅在於TARGET_IPHONE_SIMULATOR 的值,而TARGET_OS_IPHONE 則是一樣,都是真。

所以,我們區分真機模擬器的時候務必用TARGET_IPHONE_SIMULATOR來判斷,使用TARGET_OS_IPHONE將不會有效果。
PS: 一個有趣的現象(蘋果的bug Or 坑?),關於區分真機和模擬器的預編譯巨集

做法舉例如下:
我們開發過程中需要用到人臉識別,我們在 PCH(precompile prefix header) 檔案中定義一個巨集:

  • 1、在真機的時候需要編譯含有人臉識別的程式碼,定義這個巨集
  • 2、在模擬器的時候不需要編譯含有人臉識別的程式碼,不定義該巨集
#if TARGET_IPHONE_SIMULATOR  
    NSLog(@"執行在模擬器上");  
    //不定義FACE_RECOGNITION_CODE這個巨集
#else  
    NSLog(@"執行在真機上");  
    //定義FACE_RECOGNITION_CODE這個巨集
    #define FACE_RECOGNITION_CODE
#endif
  • 3、在具體程式碼中使用到的時候通過判斷該巨集是否有定義過該巨集來執行人臉識別程式碼
#ifdef FACE_RECOGNITION_CODE
       //書寫人臉識別程式碼
#endif

PS:iOS判斷真機還是模擬器的應用

擴充套件二:Xcode巨集定義

Xcode在Build Setting裡面就有一個是關於設定全域性巨集的,我們現在來解讀一下:

5293487-fbf0bb4dc6dd8083.png
Snip20170908_179.png

我們在Build Setting裡面輸入"Preprocessor Macros"即可看到上面截圖紅框中的內容。

預設我們一建立工程的時候就會定義一個巨集而且是Debug模式下才有的巨集,就是"DEBUG=1",這個的意思是定義了一個巨集,巨集名為DEBUG,巨集值為1,中間不能有空格(注意!!!)

那麼我們就可以利用這個巨集來做事情了,那麼在利用的時候有以下兩種寫法:

#if DEBUG==1
   //需要編譯的程式碼
#endif

//或者加上空格
#ifdef DEBUG == 1
   //需要編譯的程式碼
#endif
#ifdef DEBUG
   //需要編譯的程式碼
#endif

那麼在Build Setting處怎麼新增自己定義的呢?

5293487-145741a8d7b509f5.png
Snip20170721_151.png
//方式一:巨集名=巨集值(只能是數字)
KODDEBUG=10

//方式二:巨集名
KODDEBUG

注意:如果要加上巨集值,等號前後都是不能加上空格的!!!
PS:PReprocessor Macros : 全域性巨集命令的應用

PS:關於Build Setting中的設定,請參考
Build settings reference
iOS開發之Build Setting設定

擴充套件三:除錯輸出日誌

做法只需要在Build Setting的Release填上DEBUG_LOG這個欄位即可,然後再在PCH檔案上加上下面這一段

#ifndef __DEBUG_LOG__  
#define NSLog(...) NSLog(__VA_ARGS__)  
#else  
#define NSLog(...) {}  
#endif  

或者利用預設的DEBUG=1這個來判斷也是OK的,在PCH檔案中加上:

#ifdef DEBUG  
#define NSLog(...) NSLog(__VA_ARGS__)  
#else  
#define NSLog(...) {}  
#endif  
#if DEBUG == 1  
#define NSLog(...) NSLog(__VA_ARGS__)  
#else  
#define NSLog(...) {}  
#endif  

iOS列印Debug日誌的方式

擴充套件四:Build Setting設定

請詳見iOS開發之Build Setting設定

參考

預處理命令簡介
iOS編譯期和執行時系統版本判斷程式碼
一個有趣的現象(蘋果的bug Or 坑?),關於區分真機和模擬器的預編譯巨集
iOS開發必備--環境變數配置(Debug & Release)
手把手教你給一個iOS app配置多個環境變數

相關文章