講解前先說下三個詞的意思
const 常量
static 靜態(tài)
extern 查找引用
在項目中我們經(jīng)常會用到宏定義,例如#define ANIMATION_DURATION 0.5
.嗯,這么寫很方便,但是殊不知它也是有缺點的,比如說:宏定義僅僅是簡單的值替代,缺乏類型檢查機制,不包含類型信息,嵌套過多會影響程序的可讀性,降低代碼的可讀性,并且容易出錯,導(dǎo)致程序崩潰.那么我們該如何避免因為過多的使用宏定義導(dǎo)致可能出現(xiàn)的問題呢?答案是用全局常量去取代宏定義.
const CGFloat kAnimationDuration = 0.5;
,這么寫和宏的作用相同,而且不能對kAnimationDuration的值進行修改,保證了數(shù)據(jù)的準(zhǔn)確性(const保證了值不被修改)
但是這就存在一個問題,定義一個全局常量,其實是可以在整個程序中都能訪問的,方法就是用extern關(guān)鍵字(在其他的項目文件中使用extern CGFloat kAnimationDuration;
,這樣就可以直接獲取到其他文件中定義的全局常量來進行使用),默認情況下,全局常量是不安全的,因為用extern就可以在其他文件進行修改.
若不想被其他文件使用kAnimationDuration的值,或者為了避免造成值污染,就用到了static關(guān)鍵字(聲明kAnimationDuration的時候在最前面加static,static const CGFloat kAnimationDuration = 1;
).也就是說使用static以后,創(chuàng)建的全局常量只能在本文件使用了,其他文件是訪問不到的.
那么我們再反過頭來說一下這個extern CGFloat kAnimationDuration;
,通過這個獲取到的其他文件中的常量的值,可是試一下,竟然是可以進行更改的,而且編譯不會報錯,但是運行試一下,擦,崩潰了.所以為了程序安全,為了避免獲取到的這個變量被我們不經(jīng)意間更改而導(dǎo)致崩潰,我們需extern const kAnimationDuration;
,也就是多加了了一個const
,使獲取到的變量變成常量,我們獲取的值也就不能再進行修改了.
然后我們再去進行具體分析下const和static
分析之前我們需要先對指針的內(nèi)容復(fù)習(xí)下
int a = 10;
int *p = &a;
*p = 20; //a = 20
int b = 30;
p = &b;
*p = 40; //b = 40;
下面開始關(guān)于const的研究
const int *p = NULL;//這里的*p不能進行更改,但是p可以進行更改
int const *p = NULL;//效果同上
int const p; //p可以更改,*p不能更改
const int p; //效果同上
int *const p = NULL; //*p可以改,但是p不能進行更改
我們可以得出的結(jié)論是,其實主要看的是const的右邊是什么,右邊是p,則p不能進行修改,右邊是*p,則 *p不能進行修改.
下面開始關(guān)于static的研究
//寫一個循環(huán)
for (int i = 0; i < 3; i++) {
test();
}
void test(){
//1.修飾局部變量
//加了static后,讓局部變量只初始化一次,局部變量在內(nèi)存中只有一份內(nèi)存
//不會改變局部變量的作用域,只會改變其生命周期(直到程序結(jié)束,這個局部變量才會被銷毀)
static int a = 0;
a++;
NSLog(@"%d",a); //依次輸出1,2,3
}
//2.修飾全局變量
//當(dāng)多個文件都定義了同一個全局變量,當(dāng)用extern去進行引用的時候,會導(dǎo)致崩潰
//此時,用static就可以把全局變量限制在本文件使用
//所以全局變量建議加static
等等,講了這么多,好像和最前面將的全局常量代替宏定義有點關(guān)系不大啊,跑題了有點,哈哈哈.那么回到正題,如果每次使用都要用extern去引用的話,那豈不是每個文件都要extern一大堆的垃圾代碼嗎?所以,我最后要說的是我們可以創(chuàng)建一個空的類,來專門進行生命和實現(xiàn)這些代碼,和frefixheader文件一樣.
// .h文件
extern CGFloat const animationDuration;
// .m文件
static const CGFloat animationDuration = 0.5f;