屬性聲明在@implementation里與extension里的區(qū)別

當(dāng)你新建一個(gè)類的時(shí)候, Xcode 會(huì)自動(dòng)給你寫上以下代碼嗤攻。

#import <Foundation/Foundation.h>

@interface Car : NSObject

@end


#import "Car.h"

@implementation Car

@end

Objective-C 編譯器指令是以 @ 打頭集索,它通常用來描述文件中的內(nèi)容。.h 文件中 @interface 指令用來標(biāo)識(shí)文件的接口代碼的起始位置雌桑,而 @end 指令標(biāo)示該段的結(jié)束位置喇喉。在 .m 文件中,@implementation 指令用來標(biāo)識(shí)實(shí)現(xiàn)的起始位置校坑,@end 標(biāo)識(shí)結(jié)束位置

@interface 用于定義類的公共接口拣技,通常,接口被稱為 API(application programming interface)而真正使對(duì)象能夠運(yùn)行的代碼耍目,位于 @implementation 中过咬。

當(dāng)我們要給一個(gè) Car 類聲明一個(gè)發(fā)動(dòng)機(jī)屬性的時(shí)候,如果對(duì)外公開制妄,則代碼為

#import <Foundation/Foundation.h>

@interface Car : NSObject

@property (nonatomic, strong) Engine *engine;

@end

如果不對(duì)外公開掸绞,則在 .m 里的代碼為

@interface Car ()

@property (nonatomic, strong) Engine *engine;

@end

@interface Car () 看起來和 .h 里的 @interface Car : NSObject 很像,其實(shí) @interface Car () 是一個(gè)特殊的匿名 Category耕捞,即擴(kuò)展(extension)衔掸。

類別(Category)是一種為現(xiàn)有的類添加新方法的方式。

利用 Objective-C 的動(dòng)態(tài)運(yùn)行時(shí)分配機(jī)制俺抽,Category 提供了一種比繼承(inheritance)更為簡(jiǎn)潔的方法來對(duì) class 進(jìn)行擴(kuò)展敞映,無需創(chuàng)建對(duì)象類的子類就能為現(xiàn)有的類添加新方法,可以為任何已經(jīng)存在的 class 添加方法磷斧,包括那些沒有源代碼的類(如某些框架類)振愿,申明的方法不需要在 @implementation 里實(shí)現(xiàn)捷犹。

但 Category 無法向類中添加新的實(shí)例變量,類別沒有空間容納實(shí)例變量冕末。(也有一些技術(shù)可以克服類別無法增加新實(shí)例變量的局限萍歉。例如,使用全局字典來存儲(chǔ)對(duì)象與你想要關(guān)聯(lián)的額外變量之間的映射档桃。)

而 extension 可以添加新的實(shí)例變量

@property 是以 @ 開頭枪孩,所以它也是 Objective—C 編譯器指令,用于聲明屬性藻肄,并為它自動(dòng)創(chuàng)建一個(gè)帶下劃線的實(shí)例變量蔑舞,及實(shí)例變量的 setter 和 getter 方法。

而直接聲明實(shí)例變量的寫法嘹屯,即

@interface Car () {

     Engine *_engine;
}

@end

@implementation Car {

    Engine *_engine;
}

@end

從語法上說它們等效攻询。

如果只是聲明一個(gè) @implementation 里需要用到的全局變量,自然是放在 @implementation 里聲明州弟,但如果是聲明一個(gè)不對(duì)外公開的屬性呢蜕窿,比如 engine,既然是屬性呆馁,好像是需要在 extension 里聲明桐经,但如果我使用 _engine 來訪問成員變量,則并不會(huì)用到它的 setter 和 getter 方法浙滤。如果我使用點(diǎn)語法來訪問成員變量呢阴挣,點(diǎn)語法其實(shí)是調(diào)用了 getter 方法 [Car engine],而這種默認(rèn)的隱藏在代碼中多了纺腊,會(huì)影響代碼的閱讀和維護(hù)畔咧。

但 engine 明明是 Car 的一個(gè)屬性,卻聲明在 @implementation 里作為一個(gè)變量揖膜,其實(shí)實(shí)例變量也是這個(gè)對(duì)象的構(gòu)成元素誓沸,和屬性除了名字并沒有涵義上的區(qū)別。所以在 @implementation 里聲明的變量也是這個(gè)對(duì)象的屬性壹粟,只是為了區(qū)分兩種聲明方式的叫法不同而已拜隧。

另一個(gè)用 @property 和 @implementation 聲明屬性的區(qū)別就是,@property 可以給屬性添加屬性標(biāo)識(shí)符趁仙,即 assign洪添,copy,weak雀费,strong干奢,nonatomic,但其實(shí)大部分的屬性標(biāo)識(shí)符都有對(duì)應(yīng)的所有權(quán)修飾符盏袄,assign 對(duì)應(yīng) __unsafe_unretained忿峻,copy 對(duì)應(yīng) __strong 修飾符(但 copy 賦值的是被復(fù)制的對(duì)象)薄啥,strong 對(duì)應(yīng) __strong,weak 對(duì)應(yīng) __weak逛尚。id 和對(duì)象類型在沒有明確指定所有權(quán)修飾符時(shí)垄惧,默認(rèn)為 __strong 修飾符,而 @property 聲明屬性的默認(rèn)屬性標(biāo)識(shí)符為 readwrite黑低,assign, atomic赘艳。atomic 的確沒有對(duì)應(yīng)的所有權(quán)修飾符酌毡,id 和對(duì)象類型自然是沒有原子性的克握,在 iOS 開發(fā),除非特殊需要枷踏,我們都會(huì)給屬性標(biāo)識(shí)符添加 nonatomic菩暗,所以在這點(diǎn)上,@property 和 @implementation 聲明屬性倒是沒什么區(qū)別旭蠕。

在 @interface 里使用 @property 聲明屬性的時(shí)候停团,如果屬性類型為 NSString ,它的屬性標(biāo)識(shí)符是需要添加 copy 的掏熬,原因就在與佑稠,設(shè)置方法的新值有可能指向一個(gè) NSMutableString 類的實(shí)例,那么設(shè)置完屬性之后旗芬,字符串的值就可能會(huì)在對(duì)象不知情的情況下遭人更改舌胶,那在 @implementation 里聲明一個(gè) NSString 會(huì)不會(huì)有這個(gè)顧慮呢?copy 不是簡(jiǎn)單的賦值疮丛,對(duì)應(yīng)的 __strong 并不會(huì)通過 copyWithZone: 方法復(fù)制賦值源所生產(chǎn)的對(duì)象幔嫂,所以 @implementation 里聲明的 NSString 沒有 copy 作用的修飾符,但在 @implementation 里聲明即這個(gè)屬性是不對(duì)外公開的誊薄,即不會(huì)被其它對(duì)象直接修改這個(gè)屬性履恩,那你既然聲明了一個(gè) NSString 類型的屬性,自然用意就是使用一個(gè)不可變的字符串呢蔫,自然自己不會(huì)去修改它切心,如果你無意中修改了它,我只能說這是你的代碼寫錯(cuò)了片吊。所以不需要使用 copy 作用的修飾符昙衅。同理,在 extension 里使用 @property 聲明 NSString定鸟,也是不需要 copy 屬性標(biāo)識(shí)符的而涉。所以 NSString 在 @implementation 里聲明并不會(huì)有所影響。

總結(jié)
在 @implementation 里聲明并沒有缺點(diǎn)联予,但在 extension 里使用 @property 聲明屬性啼县,會(huì)有不帶來價(jià)值的隱藏代碼材原,以及 _engine 比 self.engine 更簡(jiǎn)短易讀,最后還有可以避免在 init 和 dealloc 中會(huì)去調(diào)用 self.engine季眷。(這是一件比較危險(xiǎn)的事情余蟹。)

參考資料

《iOS與OS X多線程和內(nèi)存管理》

《Objective-C基礎(chǔ)教程(第二版)》

iOS 開發(fā)中的爭(zhēng)議(一)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市子刮,隨后出現(xiàn)的幾起案子威酒,更是在濱河造成了極大的恐慌,老刑警劉巖挺峡,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件葵孤,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡橱赠,警方通過查閱死者的電腦和手機(jī)尤仍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來狭姨,“玉大人宰啦,你說我怎么就攤上這事”模” “怎么了赡模?”我有些...
    開封第一講書人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)师抄。 經(jīng)常有香客問我漓柑,道長(zhǎng),這世上最難降的妖魔是什么司澎? 我笑而不...
    開封第一講書人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任欺缘,我火速辦了婚禮,結(jié)果婚禮上挤安,老公的妹妹穿的比我還像新娘谚殊。我一直安慰自己,他們只是感情好蛤铜,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開白布嫩絮。 她就那樣靜靜地躺著,像睡著了一般围肥。 火紅的嫁衣襯著肌膚如雪剿干。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,262評(píng)論 1 308
  • 那天穆刻,我揣著相機(jī)與錄音置尔,去河邊找鬼。 笑死氢伟,一個(gè)胖子當(dāng)著我的面吹牛榜轿,可吹牛的內(nèi)容都是我干的幽歼。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼谬盐,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼甸私!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起飞傀,我...
    開封第一講書人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤皇型,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后砸烦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體弃鸦,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年外冀,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了寡键。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片掀泳。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡雪隧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出员舵,到底是詐尸還是另有隱情脑沿,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布马僻,位于F島的核電站庄拇,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏韭邓。R本人自食惡果不足惜措近,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望女淑。 院中可真熱鬧瞭郑,春花似錦、人聲如沸鸭你。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽袱巨。三九已至阁谆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間愉老,已是汗流浹背场绿。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嫉入,地道東北人焰盗。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓贱鄙,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親姨谷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子逗宁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

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

  • *本文摘錄自[饒志臻的博客] 屬性聲明在@implementation里與extension里的區(qū)別 當(dāng)你新建一個(gè)...
    xuyafei86閱讀 978評(píng)論 1 1
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)梦湘,斷路器瞎颗,智...
    卡卡羅2017閱讀 134,701評(píng)論 18 139
  • 射箭是一項(xiàng)合法野性又時(shí)尚的運(yùn)動(dòng),其愛好者一般是商界成功人士與社會(huì)名流捌议。他們所代表的自得其樂哼拔,獨(dú)善其身的姿態(tài),或許不...
    漢羿弓坊閱讀 6,748評(píng)論 0 3
  • 本文由小帥影院劇透社(jutou321)原創(chuàng)瓣颅! 有人說南方人比北方人富裕倦逐,為什么呢? 南方人沒事時(shí)候愛喝茶宫补,覺得自...
    劇透社閱讀 483評(píng)論 0 0
  • 好久沒有做蛋糕檬姥,朋友的父親生日幫她做一個(gè)》叟拢看著被攪拌機(jī)打得硬硬的蛋白忍不住拿起相機(jī)拍下他們美麗的樣子健民。 這是蛋白與...
    夢(mèng)想森林DreamForest閱讀 334評(píng)論 5 6