屬性聲明在implementation與extension的使用規(guī)范

*本文摘錄自[饒志臻的博客] 屬性聲明在@implementation里與extension里的區(qū)別

當你新建一個類的時候,Xcode會自動給你寫上以下代碼萍桌。

#import <Foundation/Foundation.h>

@interface Car : NSObject

@end

#import "Car.h"

@implementation Car

@end

Objective-C編譯器指令是以@打頭凌简,它通常用來描述文件中的內(nèi)容雏搂。.h文件中@interface指令用來標識文件的接口代碼的起始位置凸郑,而@end指令標示該段的結束位置。在.m文件中芙沥,@implementation指令用來標識實現(xiàn)的起始位置诲祸,@end標識結束位置
@interface用于定義類的公共接口,通常而昨,接口被稱為API(application programming interface)而真正使對象能夠運行的代碼救氯,位于@implementation中。
當我們要給一個Car類聲明一個發(fā)動機屬性的時候歌憨,如果對外公開着憨,則代碼為

#import <Foundation/Foundation.h>

@interface Car : NSObject

@property (nonatomic, strong) Engine *engine;

@end

如果不對外公開,則在.m里的代碼為

@interface Car ()

@property (nonatomic, strong) Engine *engine;

@end

@interface Car ()看起來和.h里的@interface Car : NSObject很像躺孝,其實@interface Car ()是一個特殊的匿名 Category享扔,即擴展(extension)。
類別(Category)是一種為現(xiàn)有的類添加新方法的方式植袍。
利用Objective-C的動態(tài)運行時分配機制惧眠,Category提供了一種比繼承(inheritance)更為簡潔的方法來對class進行擴展,無需創(chuàng)建對象類的子類就能為現(xiàn)有的類添加新方法氛魁,可以為任何已經(jīng)存在的class添加方法,包括那些沒有源代碼的類(如某些框架類)或链,申明的方法不需要在@implementation里實現(xiàn)祈纯。
但Category無法向類中添加新的實例變量,類別沒有空間容納實例變量簇爆。(也有一些技術可以克服類別無法增加新實例變量的局限。例如安寺,使用全局字典來存儲對象與你想要關聯(lián)的額外變量之間的映射软能。)
而extension可以添加新的實例變量
@property是以@開頭凳枝,所以它也是Objective—C編譯器指令,用于聲明屬性蹋订,并為它自動創(chuàng)建一個帶下劃線的實例變量捶箱,及實例變量的setter和getter方法荠锭。
而直接聲明實例變量的寫法,即

@interface Car () {
     Engine *_engine;
}

@end

@implementation Car {
    Engine *_engine;
}

@end

從語法上說它們等效。
如果只是聲明一個@implementation里需要用到的全局變量叫搁,自然是放在@implementation里聲明,但如果是聲明一個不對外公開的屬性呢,比如engine梨撞,既然是屬性,好像是需要在extension里聲明港粱,但如果我使用_engine來訪問成員變量宁炫,則并不會用到它的setter和getter方法遥昧。如果我使用點語法來訪問成員變量呢,點語法其實是調(diào)用了getter方法[Car engine],而這種默認的隱藏在代碼中多了落午,會影響代碼的閱讀和維護。
但engine明明是Car的一個屬性,卻聲明在@implementation里作為一個變量,其實實例變量也是這個對象的構成元素走哺,和屬性除了名字并沒有涵義上的區(qū)別。所以在@implementation里聲明的變量也是這個對象的屬性,只是為了區(qū)分兩種聲明方式的叫法不同而已敢朱。
另一個用@property和@implementation聲明屬性的區(qū)別就是旗们,@property可以給屬性添加屬性標識符岸梨,即assign,copy,weak纠永,strong尝江,nonatomic,但其實大部分的屬性標識符都有對應的所有權修飾符英上,assign對應__unsafe_unretained茂装,copy對應__strong修飾符(但copy賦值的是被復制的對象)善延,strong對應__strong豆茫,weak對應__weak。id和對象類型在沒有明確指定所有權修飾符時屋摇,默認為__strong修飾符火脉,而@property聲明屬性的默認屬性標識符為readwrite方援,assign, atomic先匪。atomic的確沒有對應的所有權修飾符哥桥,id和對象類型自然是沒有原子性的边涕,在iOS開發(fā),除非特殊需要褂微,我們都會給屬性標識符添加nonatomic功蜓,所以在這點上,@property和@implementation聲明屬性倒是沒什么區(qū)別宠蚂。
在@interface里使用@property聲明屬性的時候式撼,如果屬性類型為NSString,它的屬性標識符是需要添加copy的求厕,原因就在與著隆,設置方法的新值有可能指向一個NSMutableString類的實例,那么設置完屬性之后甘改,字符串的值就可能會在對象不知情的情況下遭人更改旅东,那在@implementation里聲明一個NSString會不會有這個顧慮呢?copy不是簡單的賦值十艾,對應的__strong并不會通過copyWithZone:方法復制賦值源所生產(chǎn)的對象抵代,所以@implementation里聲明的NSString沒有copy作用的修飾符,但在@implementation里聲明即這個屬性是不對外公開的忘嫉,即不會被其它對象直接修改這個屬性荤牍,那你既然聲明了一個NSString類型的屬性,自然用意就是使用一個不可變的字符串庆冕,自然自己不會去修改它康吵,如果你無意中修改了它,我只能說這是你的代碼寫錯了访递。所以不需要使用copy作用的修飾符晦嵌。同理,在extension里使用@property聲明NSString,也是不需要copy屬性標識符的惭载。所以NSString在@implementation里聲明并不會有所影響旱函。

博客:xuyafei.cn
簡書:jianshu.com/users/2555924d8c6e
微博:weibo.com/xuyafei86
Github:github.com/xiaofei86

總結

在@implementation里聲明并沒有缺點,但在extension里使用@property聲明屬性描滔,會有不帶來價值的隱藏代碼棒妨,以及_engine比self.engine更簡短易讀,最后還有可以避免在init和dealloc中會去調(diào)用self.engine含长。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末券腔,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子拘泞,更是在濱河造成了極大的恐慌纷纫,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件陪腌,死亡現(xiàn)場離奇詭異涛酗,居然都是意外死亡,警方通過查閱死者的電腦和手機偷厦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來燕刻,“玉大人只泼,你說我怎么就攤上這事÷严矗” “怎么了请唱?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長过蹂。 經(jīng)常有香客問我十绑,道長,這世上最難降的妖魔是什么酷勺? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任本橙,我火速辦了婚禮,結果婚禮上脆诉,老公的妹妹穿的比我還像新娘甚亭。我一直安慰自己,他們只是感情好击胜,可當我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布亏狰。 她就那樣靜靜地躺著,像睡著了一般偶摔。 火紅的嫁衣襯著肌膚如雪暇唾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天,我揣著相機與錄音策州,去河邊找鬼瘸味。 笑死,一個胖子當著我的面吹牛抽活,可吹牛的內(nèi)容都是我干的硫戈。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼下硕,長吁一口氣:“原來是場噩夢啊……” “哼丁逝!你這毒婦竟也來了?” 一聲冷哼從身側響起梭姓,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤霜幼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后誉尖,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體罪既,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年铡恕,在試婚紗的時候發(fā)現(xiàn)自己被綠了琢感。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡探熔,死狀恐怖驹针,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情诀艰,我是刑警寧澤柬甥,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站其垄,受9級特大地震影響苛蒲,放射性物質發(fā)生泄漏。R本人自食惡果不足惜绿满,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一臂外、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧喇颁,春花似錦寄月、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至茎毁,卻和暖如春克懊,著一層夾襖步出監(jiān)牢的瞬間忱辅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工谭溉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留墙懂,地道東北人。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓扮念,卻偏偏與公主長得像损搬,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子柜与,可洞房花燭夜當晚...
    茶點故事閱讀 45,092評論 2 355

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

  • 當你新建一個類的時候巧勤, Xcode 會自動給你寫上以下代碼。 Objective-C 編譯器指令是以 @ 打頭弄匕,它...
    AidenRao閱讀 3,996評論 11 18
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理颅悉,服務發(fā)現(xiàn),斷路器迁匠,智...
    卡卡羅2017閱讀 134,672評論 18 139
  • 2016年的春天來得特別遲剩瓶,開學卻特別早,正是春寒料峭城丧,有絲絲寒意襲來延曙。元宵節(jié)剛剛過去幾天,晚自修輪到我值班亡哄。正是...
    藍天白云1閱讀 421評論 0 0
  • 年輕時讀書搂鲫,只會看故事,懵懵懂懂磺平, 年紀再大一些,再看話劇《長恨歌》拐辽,不禁唏噓拣挪。 舞臺上道具轉換,已跨越了40年的...
    樹懶村閱讀 865評論 0 5