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

談?wù)劄楹蝘OS開發(fā)別用宏來(lái)定義常量

 更新時(shí)間:2016年08月03日 18:10:49   投稿:daisy  
最近在工程里看到很多不規(guī)范的使用,于是來(lái)寫一篇博客來(lái)讓不是很清楚的小朋友們,使用正確的規(guī)范開發(fā)ios,少埋點(diǎn)坑。

首先,預(yù)處理命令他不是一個(gè)常量!?。?!

我們來(lái)看一段代碼

#define avatar @"60"
 if (false) {
  #define avatar @"80"
 }
 NSLog(avatar);

這段代碼會(huì)輸出多少,我們將“avatar”定義為了60,然后在一個(gè)永遠(yuǎn)不會(huì)執(zhí)行的代碼里面重新定義了“avatar”為80,if語(yǔ)句中的代碼永遠(yuǎn)不會(huì)執(zhí)行,但是在編譯時(shí)期,編譯器會(huì)編譯這段代碼,而這個(gè)時(shí)候編譯器就會(huì)將avatar這個(gè)名字替換為@“80”,所以這段代碼最后的輸出結(jié)果就是80。

當(dāng)然這個(gè)時(shí)候編譯器是會(huì)有一個(gè)警告的,但是不知道有多少同學(xué)會(huì)忽略這個(gè)警告?;蛘吣銜?huì)告訴我你對(duì)警告十分敏感,不會(huì)放過他的,但是記住你不是一個(gè)人在寫代碼,可能在別人的頁(yè)面他給你重新定義了你的define,給你挖了一個(gè)大坑,還找不著.........

用const來(lái)定義一個(gè)常量

const修飾符定義的變量是不可變的,比如說你需要定義一個(gè)動(dòng)畫時(shí)間的常量,你可以這么做:

static const NSTimeInterval kAnimateDuration = 0.3;

當(dāng)你試圖去修改“ kAnimateDuration”的值的時(shí)候,編譯器會(huì)報(bào)錯(cuò)。更加重要的是用這種方法定義的常量是帶有類型信息的,而這點(diǎn)則是define不具備的。

也許你已經(jīng)發(fā)現(xiàn)了,如果你像這樣定義:

static const NSString * kUserName = @"StrongX";

你是可以修改userName的值的,(說好的常量呢~~~)

首先我們需要確定的是以下兩種寫法是一樣的:

static NSString const * kUserName = @"StrongX";
static const NSString * kUserName = @"StrongX";


也就是說const放在類型前還是類型后是一樣的效果。然后不同效果的是下面這種寫法:

static NSString * const kUserName = @"StrongX";

const 修飾的是他右邊的部分,也就是說:

static NSString const * kUserName = static NSString const (* kUserName )

static NSString * const kUserName = static NSString * const (kUserName)

當(dāng)const修飾的是(userName)的時(shí)候,不可變的是userName;“*”在C語(yǔ)言中表示
指針指向符,也就是說這個(gè)時(shí)候userName指向的內(nèi)存塊地址不可變,而內(nèi)存保存的內(nèi)容是可變的,我們來(lái)做個(gè)嘗試:

 NSLog(@"內(nèi)存地址: %x",& kUserName);
 kUserName = @"superXLX";
 NSLog(@"內(nèi)存地址: %x",& kUserName);

以上NSLog會(huì)打印*userName指向的內(nèi)存塊地址,而他的輸出是:


輸出

我們已經(jīng)發(fā)現(xiàn)當(dāng)我們改變內(nèi)存的內(nèi)存的時(shí)候他的地址并沒有發(fā)生改變,也就是說這是符合“const”修飾符的規(guī)定的。

而當(dāng)我們的修飾符是這樣的時(shí)候:

static NSString * const kUserName = @"StrongX";

我們則無(wú)法改變userName的值。

所以當(dāng)我們需要定義一個(gè)不可變的常量的時(shí)候 ,我們還是需要將“const”修飾符放到“*”指針指向符后邊才對(duì)。

一定要同時(shí)使用static和const來(lái)定義你的變量

上面已經(jīng)說了const是用來(lái)定義一個(gè)常量。而static在C語(yǔ)言中(OC中延用)則表明此變量只在改變量的輸出文件中可用(.m文件),如果你不加“static”符號(hào),那么編譯器就會(huì)對(duì)該變量創(chuàng)建一個(gè)“外部符號(hào)”,后果是什么呢?
你可以嘗試在不同編譯文件中加入以下代碼:

NSString * const kUserName = @"StrongX";

可能盡管文件之間并沒有相互引用,不存在屬性名重復(fù)的問題(因?yàn)檫@并不是一個(gè)屬性,這是一個(gè)外部符號(hào)),但是編譯器還是報(bào)錯(cuò)了:

他會(huì)告訴你在兩個(gè)目標(biāo)文件(.0文件是.m文件編譯后的輸出文件)有一個(gè)重復(fù)的符號(hào)。(OC中沒有類似C++中的名字空間的概念)

所以當(dāng)你在你自己的.m文件中需要聲明一個(gè)只有你自己可見的局部變量(k開頭)的變量的時(shí)候一定要同時(shí)使用“static”“const”兩個(gè)符號(hào)。

定義工程中的全局變量

在我們的工程中一定會(huì)定義很多全局常量,很多人的做法是會(huì)創(chuàng)建一個(gè)“ constant.h”文件,在這個(gè)文件中用#define聲明許多常量,然后將這個(gè)頭文件引入“pch”文件中,不能說這么做不對(duì),但是如同上面說的那樣define可能被修改,當(dāng)然在命名規(guī)范的情況下這種情況很少出現(xiàn),并且這樣做的效率很高。

然而蘋果更推薦另外一種做法:"extern",這樣做的優(yōu)勢(shì)是保持常量絕對(duì)不會(huì)被修改,并且一定初始化還帶有類型信息。

我們?cè)?strong>"constants.h"文件中,聲明常量

extern NSString *const XUserName;

然后在“constants.m”中定義他:

NSString *const XUserName = @"StrongX";

“extern”定義的常量必須也只能初始化一次,不滿足必須以及只能一次的條件那么編譯器就會(huì)提醒你。在定義全局變量的時(shí)候需要要注意你的命名,你可以使用規(guī)定好的前綴來(lái)命名。

“define”“extern”各有各的優(yōu)勢(shì),不過我個(gè)人還是比較推薦使用“extern”.(因?yàn)橹霸谝粋€(gè)工程中被define坑慘了!)。

以上就是本文的全部?jī)?nèi)容,希望本文提到的知識(shí)點(diǎn)對(duì)大家開發(fā)IOS時(shí)有所幫助,讓大家都能使用正確的規(guī)范開發(fā)IOS。

相關(guān)文章

  • 詳解iOS應(yīng)用中播放本地視頻以及選取本地音頻的組件用法

    詳解iOS應(yīng)用中播放本地視頻以及選取本地音頻的組件用法

    這里來(lái)為大家詳解iOS應(yīng)用中播放本地視頻以及選取本地音頻的組件用法,分別使用MPMoviePlayerControlle和MPMediaPickerController來(lái)實(shí)現(xiàn),兩個(gè)都是MediaPlayer.framework中的多媒體組件,所以我們放到一起來(lái)講.
    2016-06-06
  • iOS 隱藏tabbar代碼詳解

    iOS 隱藏tabbar代碼詳解

    這篇文章主要介紹了iOS 隱藏tabbar代碼詳解的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • ios之UIScrollerView滾動(dòng)視圖總結(jié)

    ios之UIScrollerView滾動(dòng)視圖總結(jié)

    本篇文章主要介紹了ios之UIScrollerView滾動(dòng)視圖總結(jié),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧
    2017-01-01
  • IOS多線程編程的3種實(shí)現(xiàn)方法

    IOS多線程編程的3種實(shí)現(xiàn)方法

    這篇文章主要介紹了IOS多線程編程的3種實(shí)現(xiàn)方法的相關(guān)資料,需要的朋友可以參考下
    2015-11-11
  • iOS組件化開發(fā)實(shí)戰(zhàn)記錄

    iOS組件化開發(fā)實(shí)戰(zhàn)記錄

    這篇文章主要給大家介紹了關(guān)于iOS組件化開發(fā)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • 3分鐘實(shí)現(xiàn)iOS語(yǔ)言本地化/國(guó)際化(圖文教程)

    3分鐘實(shí)現(xiàn)iOS語(yǔ)言本地化/國(guó)際化(圖文教程)

    這篇文章主要介紹了3分鐘實(shí)現(xiàn)iOS語(yǔ)言本地化/國(guó)際化,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • IOS ObjectiveC中的賦值與對(duì)象拷貝

    IOS ObjectiveC中的賦值與對(duì)象拷貝

    這篇文章主要介紹了IOS ObjectiveC中的賦值與對(duì)象拷貝的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-09-09
  • 詳解iOS開發(fā)中Keychain的相關(guān)使用

    詳解iOS開發(fā)中Keychain的相關(guān)使用

    這篇文章主要介紹了iOS開發(fā)中Keychain的相關(guān)使用,文中列舉了一個(gè)使用Keychain來(lái)保存密碼的例子,需要的朋友可以參考下
    2015-10-10
  • iOS開發(fā)之UIScrollView控件詳解

    iOS開發(fā)之UIScrollView控件詳解

    UIScrollView是一個(gè)非常重要的控件,其可以展示比設(shè)備屏幕更大區(qū)域的內(nèi)容,我們可以通過手指滑動(dòng)來(lái)查看內(nèi)容視圖的每一部分內(nèi)容,也可以通過手指捏合來(lái)對(duì)內(nèi)容視圖進(jìn)行縮放操作,我們每天開發(fā)中都不斷顯式或隱式地與UIScrollView打交道,下面給大家詳細(xì)介紹UIScrollView控件。
    2016-09-09
  • iOS開發(fā)中使用UIScrollView實(shí)現(xiàn)無(wú)限循環(huán)的圖片瀏覽器

    iOS開發(fā)中使用UIScrollView實(shí)現(xiàn)無(wú)限循環(huán)的圖片瀏覽器

    這篇文章主要介紹了iOS開發(fā)中使用UIScrollView實(shí)現(xiàn)無(wú)限循環(huán)的圖片瀏覽器的方法,感興趣的小伙伴們可以參考一下
    2016-03-03

最新評(píng)論