iOS 屬性引用self->,self.xx與_xx的區(qū)別

在iOS開(kāi)發(fā)過(guò)程中,我們用@proprety聲明一個(gè)屬性后,在代碼中我們可以用self.xx與_xx來(lái)獲取到這個(gè)屬性。但是一直有一個(gè)疑惑甘磨,那就是這兩個(gè)之間有什么區(qū)別呢?最初我一直覺(jué)得這兩個(gè)之間沒(méi)什么區(qū)別的熟呛,直到有一次宽档,我發(fā)現(xiàn)自己明明對(duì)聲明的屬性進(jìn)行了賦值尉姨,但是在使用_xx引用時(shí)發(fā)現(xiàn)為nil庵朝,這才引起我的注意。所以又厉,今天在這里對(duì)這個(gè)問(wèn)題進(jìn)行統(tǒng)一的一個(gè)說(shuō)明和學(xué)習(xí)九府。

1 @property 與 @synthesize

在說(shuō)self.xx與_xx之前,我們先了解一下@property 以及 @synthesize之間的區(qū)別和聯(lián)系覆致,說(shuō)到@property 以及 @synthesize侄旬,我們就不得不提到iOS中 成員變量和屬性 之間的區(qū)別和聯(lián)系了。

接觸iOS的人都知道煌妈,@property聲明的屬性默認(rèn)會(huì)生成一個(gè)_類型的成員變量儡羔,同時(shí)也會(huì)生成setter/getter方法。但這只是在iOS5之后璧诵,蘋果推出的一個(gè)新機(jī)制汰蜘。看老代碼時(shí)之宿,經(jīng)匙宀伲看到一個(gè)大括號(hào)里面定義了成員變量,同時(shí)用了@property聲明比被,而且還在@implementation中使用@synthesize方法色难,就像下面的代碼這樣:

image

其實(shí)泼舱,發(fā)生這種狀況根本原因是蘋果將默認(rèn)編譯器從GCC轉(zhuǎn)換為L(zhǎng)LVM(low level virtual machine),才不再需要為屬性聲明實(shí)例變量了枷莉。在沒(méi)有更改之前娇昙,屬性的正常寫法需要**成員變量 + @property + @synthesize 成員變量 **三個(gè)步驟。

如果我們只寫成員變量+ @property:

image

但更換為L(zhǎng)LVM之后依沮,編譯器在編譯過(guò)程中發(fā)現(xiàn)沒(méi)有新的實(shí)例變量后涯贞,就會(huì)生成一個(gè)下劃線開(kāi)頭的實(shí)例變量。因此現(xiàn)在我們不必在聲明一個(gè)實(shí)例變量危喉。(注意:==是不必要宋渔,不是不可以==)當(dāng)然我們也熟知,@property聲明的屬性不僅僅默認(rèn)給我們生成一個(gè)_類型的成員變量辜限,同時(shí)也會(huì)生成setter/getter方法皇拣。在.m文件中,編譯器也會(huì)自動(dòng)的生成一個(gè)成員變量_myString薄嫡。那么在.m文件中可以直接的使用_myString成員變量氧急,也可以通過(guò)屬性self.myString.都是一樣的。注意這里的self.myString其實(shí)是調(diào)用的myString屬性的setter/getter方法毫深。

此外吩坝,如果我們?cè)僮钚碌拇a中聲明一個(gè)成員變量,如下代碼所示哑蔫,那么我們只是聲明了一個(gè)成員變量钉寝,并沒(méi)有setter/getter方法。所以訪問(wèn)成員變量時(shí)闸迷,可以直接訪問(wèn)name嵌纲,也可以像C++一樣用self->name來(lái)訪問(wèn),但絕對(duì)不能用self.name來(lái)訪問(wèn)腥沽。

image

從Xcode4.4以后逮走,即iOS的@property已經(jīng)獨(dú)攬了@synthesize的功能主要有三個(gè)作用:

生成了成員變量get/set方法的聲明

生成了私有的帶下劃線的的成員變量因此子類不可以直接訪問(wèn),但是可以通過(guò)get/set方法訪問(wèn)今阳。那么如果想讓定義的成員變量讓子類直接訪問(wèn)那么只能在.h文件中定義成員變量了师溅,因?yàn)樗J(rèn)是@protected

生成了get/set方法的實(shí)現(xiàn)

值得注意的是:

**如果已經(jīng)手動(dòng)實(shí)現(xiàn)了get和set方法(兩個(gè)都實(shí)現(xiàn))的話Xcode不會(huì)再自動(dòng)生成帶有下劃線的私有成員變量了 **

因?yàn)閤Code自動(dòng)生成成員變量的目的就是為了根據(jù)成員變量而生成get/set方法的,但是如果get和set方法缺一個(gè)的話都會(huì)生成帶下劃線的變量

2 self.xx與_xx

上面我們說(shuō)到了屬性與成員變量盾舌、@property 以及 @synthesize之間的聯(lián)系與區(qū)別墓臭。同時(shí),我們提到了self.xx和_xx的一點(diǎn)區(qū)別矿筝,其中self.xx是調(diào)用的xx屬性的get/set方法起便,而_xx則只是使用成員變量_xx,并不會(huì)調(diào)用get/set方法。兩者的更深層次的區(qū)別在于榆综,通過(guò)存取方法訪問(wèn)比直接訪問(wèn)多做了一些其他的事情(例如內(nèi)存管理妙痹,復(fù)制值等),例如如果屬性在@property中屬性的修飾符有retain鼻疮,那么當(dāng)使用self.xx的時(shí)候相應(yīng)的屬性的引用計(jì)數(shù)器由于生成了setter方法而進(jìn)行加1操作怯伊,此時(shí)的retaincount為2。

擴(kuò)展:很多人覺(jué)得OC中的點(diǎn)語(yǔ)法比較奇怪判沟,實(shí)際是OC設(shè)計(jì)人員有意為之耿芹。

點(diǎn)表達(dá)式(.)看起來(lái)與C語(yǔ)言中的結(jié)構(gòu)體訪問(wèn)以及java語(yǔ)言匯總的對(duì)象訪問(wèn)有點(diǎn)類似,如果點(diǎn)表達(dá)式出現(xiàn)在等號(hào)=左邊挪哄,調(diào)用該屬性名稱的setter方法吧秕。如果點(diǎn)表達(dá)式出現(xiàn)在=右邊,調(diào)用該屬性名稱的getter方法迹炼。

OC中點(diǎn)表達(dá)式(.)其實(shí)就是調(diào)用對(duì)象的setter和getter方法的一種快捷方式砸彬,self.myString = @"張三";實(shí)際就是[self setmyString:@"張三"];

最后說(shuō)一下容易出現(xiàn)的問(wèn)題的地方,根據(jù)我個(gè)人的經(jīng)驗(yàn)斯入,

最容易出問(wèn)題的地方就是對(duì)屬性xx或成員變量_xx的初始化的地方和調(diào)用時(shí)機(jī)砂碉,直接通過(guò)例子來(lái)看,我們將屬性和實(shí)例變量的初始化放在重寫的get方法中刻两,于是我們?cè)? (void)viewDidLoad中使用_invoiceInfoImageView來(lái)進(jìn)行布局時(shí)增蹭,實(shí)際上因?yàn)樵谶@之前也沒(méi)有調(diào)用invoiceInfoImageView的get方法,所以此時(shí)invoiceInfoImageView的值其實(shí)為nil磅摹,界面上是空白的滋迈。

image

如果我們?cè)?使用self.xx來(lái)調(diào)用變量,則會(huì)調(diào)用invoiceInfoImageView的get方法偏瓤,進(jìn)行初始化杀怠,界面布局將會(huì)顯示我們想要的圖片椰憋。此外厅克,如果我們?cè)偈褂胈xx之前用self.xx調(diào)用過(guò)變量invoiceInfoImageView,則同樣會(huì)調(diào)用其get方法從而觸發(fā)invoiceInfoImageView的初始化橙依,這樣也不會(huì)影響布局证舟。

image

還有一點(diǎn)值得注意的就是我們前面提到過(guò)的,如果我們同時(shí)手動(dòng)重寫了一個(gè)屬性的get和set方法的話窗骑,Xcode不會(huì)再自動(dòng)生成帶有下劃線的私有成員變量了女责。如下圖所示,在我們只定義了get方法時(shí)一切都沒(méi)有問(wèn)題创译,但是一旦我們又重寫set方法抵知,會(huì)發(fā)現(xiàn)用到_xx的地方就會(huì)報(bào)錯(cuò)。

image

轉(zhuǎn)發(fā)參考文章:

iOS學(xué)習(xí)——屬性引用self.xx與_xx的區(qū)別 - mukekeheart - 博客園

作者鏈接:http://www.reibang.com/p/62ed57cedf11

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市刷喜,隨后出現(xiàn)的幾起案子残制,更是在濱河造成了極大的恐慌,老刑警劉巖掖疮,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件初茶,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡浊闪,警方通過(guò)查閱死者的電腦和手機(jī)恼布,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)搁宾,“玉大人折汞,你說(shuō)我怎么就攤上這事「峭龋” “怎么了字支?”我有些...
    開(kāi)封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)奸忽。 經(jīng)常有香客問(wèn)我堕伪,道長(zhǎng),這世上最難降的妖魔是什么栗菜? 我笑而不...
    開(kāi)封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任欠雌,我火速辦了婚禮,結(jié)果婚禮上疙筹,老公的妹妹穿的比我還像新娘富俄。我一直安慰自己,他們只是感情好而咆,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布霍比。 她就那樣靜靜地躺著,像睡著了一般暴备。 火紅的嫁衣襯著肌膚如雪悠瞬。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天涯捻,我揣著相機(jī)與錄音浅妆,去河邊找鬼。 笑死障癌,一個(gè)胖子當(dāng)著我的面吹牛凌外,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播涛浙,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼康辑,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼摄欲!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起疮薇,我...
    開(kāi)封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蒿涎,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后惦辛,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體劳秋,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡滩褥,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年嫂粟,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了钓账。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片议慰。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡这橙,死狀恐怖趣些,靈堂內(nèi)的尸體忽然破棺而出瓷耙,到底是詐尸還是另有隱情太伊,我是刑警寧澤剿另,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布箫锤,位于F島的核電站,受9級(jí)特大地震影響雨女,放射性物質(zhì)發(fā)生泄漏谚攒。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一氛堕、第九天 我趴在偏房一處隱蔽的房頂上張望馏臭。 院中可真熱鬧,春花似錦讼稚、人聲如沸括儒。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)帮寻。三九已至,卻和暖如春赠摇,著一層夾襖步出監(jiān)牢的瞬間固逗,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工蝉稳, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抒蚜,地道東北人掘鄙。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓耘戚,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親操漠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子收津,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容