7: 在對象內(nèi)部盡量直接訪問實(shí)例變量

爭論:在對象之外訪問實(shí)例變量時,總是應(yīng)該通過屬性來做.然而在對象內(nèi)部訪問實(shí)例變量時,又該如何呢?這個問題在OC的開發(fā)中一直存在爭論,筆者認(rèn)為:

除了幾種特殊情況之外,強(qiáng)烈建議大家在讀取實(shí)例變量時采用直接訪問的形式,而在設(shè)置實(shí)例變量的時候通過屬性來做.

<h5>方法探討:</h5>

請看下面這個類:

<pre><code>@interface CWGPerson : NSObject</code>
<code>@property (nonatomic, copy) NSString *firstName;</code>
<code>@property (nonatomic, copy) NSString *lastName;</code>
<code>- (NSString *)fullName;</code>
<code>- (void)setFullName:(NSString *)fullName;</code>
<code>@end</code></pre>

  • 通過存取方法來實(shí)現(xiàn)fullName的setter和getter方法:

<pre><code>- (NSString *)fullName {</code>
<code> return [NSString stringWithFormat:@"%@, %@", self.firstName, self.lastName];
</code>
<code>}</code>
<code>- (void)setFullName:(NSString *)fullName {</code>
<code> NSArray *components = [fullName componentsSeparateByString:@" "];</code>
<code> self.firstName = components[0];</code>
<code> self.lastName = components[1];</code>
<code>}</code></pre>

  • 直接訪問實(shí)例變量實(shí)現(xiàn)fullName的setter和getter方法:

<pre><code> - (NSString *)fullName {
</code>
<code> return [NSString stringWithFormat:@"%@, %@", _firstName, _lastName];</code>
<code>}</code>
<code>- (void)setFullName:(NSString *)fullName {</code>
<code> NSArray *components = [fullName componentsSeparateByString:@" "];</code>
<code> _firstName = components[0];</code>
<code> _lastName = components[1];</code>
<code>}</code></pre>

這兩種實(shí)現(xiàn)區(qū)別:

  • 直接訪問實(shí)例變量速度快:因?yàn)椴唤?jīng)過OC的"方法派發(fā)"步驟,編譯器所生成的代碼會直接訪問保存對象實(shí)例變量的那塊內(nèi)存.
  • 直接訪問實(shí)例變量繞過了屬性“內(nèi)存管理語義”:直接訪問屬性不會調(diào)用setter方法,這就繞過了為相關(guān)屬相所定義的"內(nèi)存管理語義".比如說:如果在ARC下直接訪問一個聲明為copy的屬性,那么并不會拷貝該屬性,只會保留新值并釋放舊值.
  • 直接訪問實(shí)例變量不會觸發(fā)"鍵值觀察者(KVO)通知":這樣做是否會產(chǎn)生問題,還取決于具體對象行為.
  • 通過屬性來訪問有助于排查與之相關(guān)的錯誤:因?yàn)榭梢栽?獲取方法"和"設(shè)置方法"中加斷點(diǎn),跟蹤該屬性調(diào)用者及其訪問時機(jī).

<h5>合理方法:</h5>

  • 說了這么多,其實(shí)有一種合理的折中方法:

在寫入實(shí)例變量時,通過其"設(shè)置方法"來做,而在讀取實(shí)例變量時,則直接訪問它.

  • 優(yōu)勢:

此辦法既能提高讀取操作速度,又能控制對屬性的寫入操作.

<h5>注意問題:</h5>

之所以要通過"設(shè)置方法"來寫入實(shí)例變量,其首要原因在于:這樣能確保相關(guān)屬性的"內(nèi)存管理語義"得以貫徹.但是,選用這樣的做法,還是要注意幾個問題:

  • 在初始化方法init和dealloc方法中應(yīng)該直接通過實(shí)例變量來訪問.

<pre><code>// init</code>
<code>-(id)init {</code>
<code> self = [super init];</code>
<code> if (self) {</code>
<code> _count = [[NSNumber alloc] initWithInteger:0];</code>
<code> }</code>
<code> return self;</code>
<code>}</code>

<code> dealloc</code>
<code>- (void)dealloc {</code>
<code> [_count release];</code>
<code> [super dealloc];</code>
<code>}</code></pre>

在 init 和 dealloc 中,對象的存在與否還不確定,所以給對象發(fā)消息可能不會成功牵现。

  • 另外一種就是"惰性初始化".在這樣的情況下必需通過"獲取方法"來訪問屬性.否則實(shí)例變量就永遠(yuǎn)無法初始化.

<pre><code>-(NSArray *)array{</code>
<code> if (!_array) {</code>
<code> _array = @[@"aa",@"bb"];</code>
<code> }</code>
<code> return _array;</code>
<code>}</code></pre>

<h5>總結(jié):</h5>

  • 在對象內(nèi)讀數(shù)據(jù), 應(yīng)該直接通過實(shí)例變量來讀,而寫數(shù)據(jù)時,則應(yīng)該通過屬性來寫.
  • 在初始化方法及dealloc方法中,總是應(yīng)該直接通過實(shí)例變量來讀寫數(shù)據(jù)(除一些特殊子類中).
  • 有時會使用惰性初始化技術(shù)配置數(shù)據(jù),這樣的情況下,需要通過屬性來讀取數(shù)據(jù).
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市朽缴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌水援,老刑警劉巖密强,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件茅郎,死亡現(xiàn)場離奇詭異,居然都是意外死亡或渤,警方通過查閱死者的電腦和手機(jī)只洒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來劳坑,“玉大人,你說我怎么就攤上這事成畦【喾遥” “怎么了?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵循帐,是天一觀的道長框仔。 經(jīng)常有香客問我,道長拄养,這世上最難降的妖魔是什么离斩? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮瘪匿,結(jié)果婚禮上跛梗,老公的妹妹穿的比我還像新娘。我一直安慰自己棋弥,他們只是感情好核偿,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著顽染,像睡著了一般漾岳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上粉寞,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天尼荆,我揣著相機(jī)與錄音,去河邊找鬼唧垦。 笑死捅儒,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的业崖。 我是一名探鬼主播野芒,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼双炕!你這毒婦竟也來了狞悲?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤妇斤,失蹤者是張志新(化名)和其女友劉穎摇锋,沒想到半個月后丹拯,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡荸恕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年乖酬,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片融求。...
    茶點(diǎn)故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡咬像,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出生宛,到底是詐尸還是另有隱情县昂,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布陷舅,位于F島的核電站倒彰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏莱睁。R本人自食惡果不足惜待讳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望仰剿。 院中可真熱鬧创淡,春花似錦、人聲如沸南吮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽旨袒。三九已至汁针,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間砚尽,已是汗流浹背施无。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留必孤,地道東北人猾骡。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像敷搪,于是被迫代替她去往敵國和親兴想。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評論 2 348

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