天天看點

iOS static、const和extern相關的問題

static

static分兩種情況,修飾局部變量和全局變量。

我們首先要搞清楚生命周期和作用域的概念。

生命周期:這個變量能存活多久,它所占用的記憶體什麼時候配置設定,什麼時候收回。

作用域:說白了就是這個變量在什麼區域是可見的,可以拿來用的。

static修飾局部變量

在函數或者說代碼塊内部聲明的變量叫局部變量。

局部變量

局部變量是存儲在棧區的,它的生命周期是整個代碼塊,作用域也是整個代碼塊,一旦出了這個代碼塊,存儲局部變量的這個棧記憶體就會被回收,局部變量也就被銷毀了。看一個例子:

iOS static、const和extern相關的問題

列印結果:

iOS static、const和extern相關的問題

這個其實很好了解,局部變量a是在test方法的代碼塊内聲明的,是以它的生命周期就是這個代碼塊,當我們調用完一次test方法後,局部變量a就被銷毀了,不存在了。在下一次調用test方法時又在棧區重新申請了記憶體。

當我們用static修飾局部變量時,變量被稱為靜态局部變量,這個靜态局部變量和全局變量,靜态全局變量一樣,是存儲在靜态存儲區。**由于存儲在靜态存儲區,是以這塊記憶體直到程式結束才會銷毀。也就是說,靜态局部變量的生命周期是整個源程式。但是它隻在聲明它的代碼塊可見,也就是說它的作用域是聲明它的代碼塊。我們把局部變量a用static修飾:

iOS static、const和extern相關的問題

看一下列印結果:

iOS static、const和extern相關的問題

當我們第一次調用test方法時,在靜态存儲區申請了一塊記憶體嗎,這塊記憶體名字叫a,裡面裝着數字0,然後把數字0加1,變成了1,當第二次調用test方法時,會去靜态存儲區查找有沒有一塊記憶體叫a,如果有那就不用重新配置設定記憶體初始化,這裡找到了這塊叫a的記憶體,是以不用進行初始化,是以a裡面還是裝的1然後對1加1,得到了2.

static修飾全局變量

當全局變量沒有使用static修飾符時,其存儲在靜态存儲區,直到程式結束才銷毀。也就是其作用域是整個源程式。我們可以使用extern關鍵字來引用這個全局變量。

Test.h:

iOS static、const和extern相關的問題

ViewController.m:

iOS static、const和extern相關的問題

static修飾,列印結果:

當全局變量使用static修飾時,其生命周期沒有變,依舊是在程式結束時才銷毀。但是其作用域變了,以前是整個源程式,現在隻限于申明它的這個檔案才可見,即使用extern引用也不行,比如我們把上面的例子中globalVar前面用static修飾,那麼程式就會報錯:

iOS static、const和extern相關的問題

沒有static修飾,列印結果:

iOS static、const和extern相關的問題

總結:

static修飾局部變量:将局部變量的本來配置設定在棧區改為配置設定在靜态存儲區,也就改變了局部變量的生命周期。

static修飾全局變量:本來是在整個源程式的所有檔案都可見,static修飾後,改為隻在申明自己的檔案可見,即修改了作用域。

const

const修飾變量主要強調變量是不可修改的。我們看一下下面代碼段:

iOS static、const和extern相關的問題

從結果可以看到變量a的值修改成功,那麼我們将變量a用const修飾試一試:

iOS static、const和extern相關的問題

使用const修飾變量a之後,a的值就不能修改了,是以這裡修改就不成功了。

需要注意的一點是,const修飾的是其右邊的值,也就是const右邊的這個整體的值不能改變。

下面例子是const修飾*str這個整體,是以這個整體不能改變,這個整體是str指向的記憶體中的值。

iOS static、const和extern相關的問題

下面例子是const修飾str的,是以str指向的位址不能改變,是以這裡的改變就産生了錯誤。

iOS static、const和extern相關的問題

一般聯合使用static和const來定義一個隻能在本檔案中使用的,不能修改的變量:

iOS static、const和extern相關的問題

這樣定義相對于用#define來定義的話,優點就在于它指定了變量的類型,而#define是不能指定變量的類型的。

extern

extern主要是用來引用全局變量,它的原理就是先在本檔案中查找,本檔案中查找不到再到其他檔案中查找。

常把extern和const聯合使用在項目中建立一個檔案,這個檔案檔案中包含整個項目中都能通路的全局常量。比如我們在項目中建立的這個檔案為LMConst.h,LMConst.m。

LMConst.h:

iOS static、const和extern相關的問題

LMConst.m:

iOS static、const和extern相關的問題

pch檔案:

iOS static、const和extern相關的問題

然後我們就可以直接在其他檔案中使用NOTIFICATION_NAME這個字元串常量了:

iOS static、const和extern相關的問題