static
static分兩種情況,修飾局部變量和全局變量。
我們首先要搞清楚生命周期和作用域的概念。
生命周期:這個變量能存活多久,它所占用的記憶體什麼時候配置設定,什麼時候收回。
作用域:說白了就是這個變量在什麼區域是可見的,可以拿來用的。
static修飾局部變量
在函數或者說代碼塊内部聲明的變量叫局部變量。
局部變量
局部變量是存儲在棧區的,它的生命周期是整個代碼塊,作用域也是整個代碼塊,一旦出了這個代碼塊,存儲局部變量的這個棧記憶體就會被回收,局部變量也就被銷毀了。看一個例子:

列印結果:
這個其實很好了解,局部變量a是在test方法的代碼塊内聲明的,是以它的生命周期就是這個代碼塊,當我們調用完一次test方法後,局部變量a就被銷毀了,不存在了。在下一次調用test方法時又在棧區重新申請了記憶體。
當我們用static修飾局部變量時,變量被稱為靜态局部變量,這個靜态局部變量和全局變量,靜态全局變量一樣,是存儲在靜态存儲區。**由于存儲在靜态存儲區,是以這塊記憶體直到程式結束才會銷毀。也就是說,靜态局部變量的生命周期是整個源程式。但是它隻在聲明它的代碼塊可見,也就是說它的作用域是聲明它的代碼塊。我們把局部變量a用static修飾:
看一下列印結果:
當我們第一次調用test方法時,在靜态存儲區申請了一塊記憶體嗎,這塊記憶體名字叫a,裡面裝着數字0,然後把數字0加1,變成了1,當第二次調用test方法時,會去靜态存儲區查找有沒有一塊記憶體叫a,如果有那就不用重新配置設定記憶體初始化,這裡找到了這塊叫a的記憶體,是以不用進行初始化,是以a裡面還是裝的1然後對1加1,得到了2.
static修飾全局變量
當全局變量沒有使用static修飾符時,其存儲在靜态存儲區,直到程式結束才銷毀。也就是其作用域是整個源程式。我們可以使用extern關鍵字來引用這個全局變量。
Test.h:
ViewController.m:
static修飾,列印結果:
當全局變量使用static修飾時,其生命周期沒有變,依舊是在程式結束時才銷毀。但是其作用域變了,以前是整個源程式,現在隻限于申明它的這個檔案才可見,即使用extern引用也不行,比如我們把上面的例子中globalVar前面用static修飾,那麼程式就會報錯:
沒有static修飾,列印結果:
總結:
static修飾局部變量:将局部變量的本來配置設定在棧區改為配置設定在靜态存儲區,也就改變了局部變量的生命周期。
static修飾全局變量:本來是在整個源程式的所有檔案都可見,static修飾後,改為隻在申明自己的檔案可見,即修改了作用域。
const
const修飾變量主要強調變量是不可修改的。我們看一下下面代碼段:
從結果可以看到變量a的值修改成功,那麼我們将變量a用const修飾試一試:
使用const修飾變量a之後,a的值就不能修改了,是以這裡修改就不成功了。
需要注意的一點是,const修飾的是其右邊的值,也就是const右邊的這個整體的值不能改變。
下面例子是const修飾*str這個整體,是以這個整體不能改變,這個整體是str指向的記憶體中的值。
下面例子是const修飾str的,是以str指向的位址不能改變,是以這裡的改變就産生了錯誤。
一般聯合使用static和const來定義一個隻能在本檔案中使用的,不能修改的變量:
這樣定義相對于用#define來定義的話,優點就在于它指定了變量的類型,而#define是不能指定變量的類型的。
extern
extern主要是用來引用全局變量,它的原理就是先在本檔案中查找,本檔案中查找不到再到其他檔案中查找。
常把extern和const聯合使用在項目中建立一個檔案,這個檔案檔案中包含整個項目中都能通路的全局常量。比如我們在項目中建立的這個檔案為LMConst.h,LMConst.m。
LMConst.h:
LMConst.m:
pch檔案:
然後我們就可以直接在其他檔案中使用NOTIFICATION_NAME這個字元串常量了: