欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Objective-C const常量的優(yōu)雅使用方法

 更新時(shí)間:2022年08月08日 11:36:09   作者:小橘爺  
這篇文章主要為大家介紹了Objective-C const常量的優(yōu)雅使用方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

在編寫代碼時(shí)經(jīng)常要使用常量,來替代 magic number。比較簡(jiǎn)單的做法是通過預(yù)處理指令 #define 來實(shí)現(xiàn)。

#define ANIMATION_DURATION 0.3 

上述預(yù)處理指令會(huì)在編譯時(shí)的預(yù)處理階段會(huì)將代碼中 ANIMATION_DURATION 字符串替換為 0.3。這種定義常量的方式比較簡(jiǎn)便,但是存在兩個(gè)問題:

  • 丟失了類型信息。
  • 若該預(yù)處理指令聲明在頭文件中,引入該頭文件的代碼,ANIMATION_DURATION 都會(huì)被替換,可能出現(xiàn)沖突。

Objective-C 的常量聲明方式

幸運(yùn)的是,Objective-C 中提供了 const 關(guān)鍵字,可以用來定義常量。const 關(guān)鍵字可以對(duì)變量加以限定,使其值不能被改變,在整個(gè)作用域中都保持固定。

const NSTimeInterval kAnimationDuration = 0.3;

這種方式定義的常量包含類型信息,且在編譯時(shí)即可檢查是否與其他常量出現(xiàn)沖突。如果試圖修改由 const 修飾符所聲明的變量,那么編譯器就會(huì)報(bào)錯(cuò)。

如果常量?jī)H在某個(gè)實(shí)現(xiàn)文件中使用,還應(yīng)該加上 static 關(guān)鍵字,否則會(huì)被視為全局常量。若不使用 static,編譯器會(huì)為它創(chuàng)建一個(gè)外部符號(hào),若另一個(gè)編譯單元中也聲明了同名變量,就會(huì)報(bào)錯(cuò)。

static const NSTimeInterval kAnimationDuration = 0.3;

當(dāng)一個(gè)變量同時(shí)使用了 staticconst,那么編譯器并不會(huì)創(chuàng)建符號(hào),而是會(huì)像 #define 預(yù)處理指令一樣,把所有遇到的變量替換為常值。

有時(shí)候需要把一個(gè)常量暴露給外界使用,比如通知,此類常量需放在全局符號(hào)表中??梢允褂?extern 關(guān)鍵字,在頭文件中進(jìn)行聲明:

// .h
extern NSString * const AFNetworkingTaskDidResumeNotification;
// .m
NSString * const AFNetworkingTaskDidResumeNotification = @"com.alamofire.networking.task.resume";

該常量在頭文件中聲明,在實(shí)現(xiàn)文件中定義。需要注意的是 const 寫在指針類型的右邊意味著該指針的指向不可被改變,若寫在左邊意味著該指針指向的內(nèi)容不可被改變。

按上述方式實(shí)現(xiàn)并定義后,在編譯時(shí)生成目標(biāo)文件時(shí),編譯器會(huì)在數(shù)據(jù)段為字符串分配存儲(chǔ)空間。

Foundation 框架中,蘋果為了兼容 C++ 中對(duì) extern 的使用,提供了宏:

#if defined(__cplusplus)
#define FOUNDATION_EXTERN extern "C"
#else
#define FOUNDATION_EXTERN extern
#endif
#define FOUNDATION_EXPORT FOUNDATION_EXTERN
#define FOUNDATION_IMPORT FOUNDATION_EXTERN

一個(gè) C++ 程序中可能包含其他語(yǔ)言編寫的部分代碼,同樣,C++ 編寫的代碼片段也可能被用在其他語(yǔ)言編寫的代碼中。但是,不同語(yǔ)言編寫的代碼相互調(diào)用是困難的,更何況用同一種語(yǔ)言編寫,使用不同編譯器進(jìn)行編譯的情況。因?yàn)椋煌Z(yǔ)言或者同種語(yǔ)言在不同編譯器上編譯時(shí),在注冊(cè)變量,傳遞參數(shù)和參數(shù)在棧上的布局上可能存在差異。

為了使它們遵守統(tǒng)一規(guī)則,可以使用 extern 指定一個(gè)編譯和鏈接規(guī)約。extern "C" 指令中的 C,表示的是一種編譯和鏈接規(guī)約,而不是一種語(yǔ)言。C 表示符合 C 語(yǔ)言的編譯和鏈接規(guī)約的任何語(yǔ)言。

還要說明的是,extern "C" 指令指定的編譯和鏈接規(guī)約,不會(huì)影響語(yǔ)義,只是改變編譯和鏈接的方式。

FOUNDATION_EXPORTFOUNDATION_IMPORT 是用來兼容 Win32 應(yīng)用程序的,移動(dòng)端開發(fā)可以忽略。

所以上述對(duì)全局常量的聲明,可以寫成:

// .h
FOUNDATION_EXPORT NSString * const AFNetworkingTaskDidResumeNotification;
// .m
NSString * const AFNetworkingTaskDidResumeNotification = @"com.alamofire.networking.task.resume";

在 Objective-C 中使用 let 來聲明常量

使用過 Swift 的同學(xué),一定對(duì)其聲明常量的方式的簡(jiǎn)潔性印象深刻,在 Swift 中聲明常量的方式如下所示:

let kAnimationDuration = 0.3

之所以能如此簡(jiǎn)潔,是因?yàn)?Swift 具有 let 關(guān)鍵字和類型推斷的能力,但其實(shí)在 Objective-C 中也可以通過類似的方式來書寫常量。

Objective-C 中有一個(gè)關(guān)鍵字,是 __auto_type,可以實(shí)現(xiàn)類似 Swift 中類型推斷能力的關(guān)鍵字,如下所示:

const __auto_type kAnimationDuration = 0.3;

可能對(duì)于簡(jiǎn)單的數(shù)據(jù)類型,這樣的優(yōu)勢(shì)不是很明顯,但是對(duì)于具有復(fù)雜泛型的類型來說,可以說優(yōu)勢(shì)很大了:

// 舊方式
NSArray<NSDictionary<NSString *, NSString *> *> *models = ...;
// 新方式
__auto_type models = ...;

同時(shí),可以通過宏的方式,來減少 __auto_type 的書寫,即可實(shí)現(xiàn)通過 let 聲明常量,var 聲明變量。其中 auto 關(guān)鍵字是為了兼容 C++。

#if defined(__cplusplus)
#define let auto const
#else
#define let const __auto_type
#endif
#if defined(__cplusplus)
#define var auto
#else
#define var __auto_type
#endif

聲明了上面的宏之后,就可以直接使用了:

let kAnimationDuration = 0.3;

以上就是Objective-C const常量的優(yōu)雅使用方法的詳細(xì)內(nèi)容,更多關(guān)于Objective-C const常量的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論