在ios開發(fā)中為什么要多用類型常量,少用#define預(yù)處理指令

我們?cè)趇os開發(fā)中都會(huì)經(jīng)常定義常量,比如說,在一個(gè)頁面上播放一個(gè)動(dòng)畫,在很多開發(fā)者來說都會(huì)把八方動(dòng)畫的時(shí)間提取為一個(gè)常量,我想想很多人都會(huì)這樣做,包括我自己。

define ANIMATION_DURATTON 1.5

這段預(yù)處理指令會(huì)吧代碼中的ANIMATION_DURATTON字符串替換成1.5,不過這樣定義出來的常量沒有類型信息,預(yù)處理過程中會(huì)把碰到的所有的ANIMATION_DURATTON替換成為1.5,這樣的話,假設(shè)此指令生命在某個(gè)頭文件中,那么所有引入這個(gè)頭文件的代碼,其ANIMATION_DURATTON都會(huì)被替換。

想要解決這個(gè)問題最好的辦法就是設(shè)法利用編譯器的某些特性,有個(gè)辦法比用預(yù)處理指令來定義常量更好,如例:

static const NSSTimeInterval kAnimationDuration = 1.5;

此方式定義的常量包含類型信息,其好處是清楚的描述了常量的含義,由此可以知道該常量的類型為NSSTimeInterval。

定義常量的位置很重要,我們總喜歡在頭文件里聲明預(yù)處理指令,這樣做真的很糟糕,當(dāng)常量名稱有可能互相沖突時(shí)更是如此。例如,ANIMATION_DURATTON這個(gè)常量名就不該定義在頭文件,應(yīng)為所喲引入這份頭文件的其他文件都會(huì)出現(xiàn)這個(gè)名字。其實(shí)就連用static const定義的那個(gè)常量也不應(yīng)該出現(xiàn)在頭文件里。因?yàn)镺bjective-C沒有“名稱空間”這一概念,所以那樣做就等于聲明了一個(gè)名叫kAnimationDuration全局變量,因此名稱必須加上前綴,以表明所屬的類。

如果不打算公開某個(gè)常量,就應(yīng)該在使用該常量的實(shí)現(xiàn)文件里定義,例如:

//EOCAnimatedView.h

import <UIKit/UIKit.h>

@interface EOCAnimatedView : UIView

-(void)animate;

@end

//EOCAnimatedView.m

import "EOCAnimatedView.h"

static const NSSTimeInterval kAnimationDuration = 1.5;

@implementation EOCAnimatedView

-(void)animate{

}

@end

變量一定要同時(shí)用static和const來聲明,事實(shí)上,一個(gè)變量既聲明為static,又聲明為const,那么編譯器根本不會(huì)創(chuàng)建符號(hào),而會(huì)像#define預(yù)處理指令一樣把所有遇到的變量都替換成常值,不過要記住,用這種方式定義的常量帶有類型信息。

有時(shí)候需要對(duì)外公開一個(gè)常量,此類常量需要放在“全局符號(hào)表”中,以便可以在定義該常量的編譯單元之外使用,因此其定義方式與上例演示的static const有所不一樣:

//In the header file

extern NSString *const EOCStringConstant;

//In the implementation file

NSString *const EOCStringConstant=@"VALUE";

這個(gè)常量在頭文件中“聲明”,且在實(shí)現(xiàn)文件中“定義”,const修飾符在常量類型中的位置,常量從右至左解讀。編譯器看到頭文件中的extern關(guān)鍵字,就能明白如何明白在引入此文件的代碼中處理該常量了。這個(gè)關(guān)鍵字就會(huì)告訴編譯器,在全局符號(hào)表中將會(huì)有一個(gè)名叫EOCStringConstant的符號(hào),編譯器無需查看其定義,既允許此代碼使用此常量,因?yàn)樗喇?dāng)鏈接成二進(jìn)制文件之后,肯定能找到這個(gè)常量。

此類常量必須要定義,且只能定義一次,通常將其定義在與聲明該常量的頭文件相關(guān)的實(shí)現(xiàn)文件里,由實(shí)現(xiàn)文件生成目標(biāo)文件時(shí),編譯器會(huì)在“數(shù)據(jù)段”為字符串分配存儲(chǔ)空間。連接器會(huì)把此目標(biāo)文件和其他的目標(biāo)文件相鏈接,以生成最終的二進(jìn)制文件,凡使用到EOCStringConstant這個(gè)全局符號(hào)的地方,鏈接器都能將其解析。

注意常量的名字,為避免名稱沖突,最好使用與之相關(guān)的類名作為前綴。

這樣定義的常量?jī)?yōu)于使用#define預(yù)處理命令,因?yàn)榫幾g器確保常量的值不會(huì)變,總之勿使用預(yù)處理指令定義常量,而應(yīng)該用戒指編譯器的特性來確保常量的正確。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容