iOS 探討category和extension

一曹锨、分類(Category)

想必大家都知道我們可以在分類中為某個類擴展方法舵盈,并且通過分類添加的方法的優(yōu)先級還高于原始類中的方法,即如果分類中和原始類中有相同的方法驮宴,那我們調(diào)用時是優(yōu)先調(diào)用通過分類添加的方法逮刨。
既然通過分類能給類添加方法,那能不能給類添加屬性呢堵泽?屬性中綁定了一個成員變量修己,那分類又能不能給類添加成員變量呢?今天元宵節(jié)迎罗,閑著沒事睬愤,就此調(diào)研了一番。

論點

(1) 分類可以給類添加屬性
(2) 分類不可以給一個類擴展成員變量的`

先嘮嘮嗑

強調(diào)一下纹安,分類不是類程癌,它只是一個類似匿名擴展(下面會討論擴展)的模塊赢笨,用于擴展給類添加方法泵肄,便于協(xié)作楚堤、分模塊的開發(fā),你看看蘋果提供的很多API都是這樣塔粒,蘋果會寫很多分類來給某個類添加不同的功能结借,一來結(jié)構(gòu)清晰,二來也便于協(xié)同開發(fā)卒茬,可以每個人負(fù)責(zé)一個分類船老。

我們都知道咖熟,OC的世界里,任何集成自NSObject的對象都有isa指針努隙,他本質(zhì)是一個結(jié)構(gòu)體指針,但是對于Category來說辜昵,他是沒有isa指針的荸镊,好了,下面進行論證一番堪置。

論據(jù)

先說說屬性躬存,屬性是對成員變量的一個封裝,當(dāng)我們聲明一個屬性的時候舀锨,Xcode會給我們默認(rèn)創(chuàng)建一個 _屬性名 命名的成員變量岭洲,也會給我們自動創(chuàng)建getter和setter方法。當(dāng)然我們也可以用@synthesize指定其關(guān)聯(lián)的變量

【例如】給屬性name指定其關(guān)聯(lián)的變量@synthesize name = xxx坎匿;執(zhí)行self.name的時候盾剩,其實是操作的是實例變量xxx,而不是_name了替蔬。

窩草告私,扯遠(yuǎn)了,回歸正傳承桥。驻粟。

所以我們要添加一個屬性得有三樣?xùn)|西,setter凶异、getter以及關(guān)聯(lián)的實例變量蜀撑。

在分類中Xcode不會為我們自動創(chuàng)建setter、getter方法剩彬,但是我們可以手動實現(xiàn)酷麦,但是如何把一個變量關(guān)聯(lián)到屬性上呢,直接聲明一個全局變量不行嗎喉恋,事實證明不太行贴铜,對于getter方法還好說,直接返回一個變量就行瀑晒,可是setter方法卻不行绍坝,因為你要找到該屬性關(guān)聯(lián)的變量你才能給人家賦值啊,怎么辦苔悦?怎么辦轩褐??經(jīng)過調(diào)研發(fā)現(xiàn)這只能用runtime的對象關(guān)聯(lián)來實現(xiàn)了

.m文件中
// 定義關(guān)聯(lián)的key
static const char *key = "name";

@implementation NSObject (Property)

-  (NSString *)name {
  // 根據(jù)關(guān)聯(lián)的key玖详,獲取關(guān)聯(lián)的值把介。
  return objc_getAssociatedObject(self, key);
}

-  (void)setName:(NSString *)name {
  // 參數(shù)一:目標(biāo)對象
  // 參數(shù)二:關(guān)聯(lián)的key勤讽,可以通過這個key獲取
  // 參數(shù)三:關(guān)聯(lián)的value
  // 參數(shù)四:關(guān)聯(lián)的策略
  objc_setAssociatedObject(self, key, name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end

看到這里你也許就會說,這不是把變量給添加上去了嗎拗踢?我表示默默一笑脚牍,如果你在原始類中打印IVarList你就會發(fā)現(xiàn)并沒有這個變量,只能打印出添加的屬性巢墅。
其實對象關(guān)聯(lián)只是把屬性關(guān)聯(lián)上去了诸狭,并沒有把變量添加進去,說了這么多這回你該信了吧君纫。

原因就是分類不是類驯遇,他沒有isa指針,下面是isa指針的代碼蓄髓,可以看出他本質(zhì)上是一個objc_class結(jié)構(gòu)體叉庐,通過isa指針才能找指向裝有變量的ivars容器,也就是說你都不知道裝有變量的容器ivars会喝,你怎么去給它生猴子啊陡叠,但是奇怪了,ISA指針里沒有指向?qū)傩詳?shù)組的指針肢执,沒有是對的匾竿,要不然這一段的解釋就廢了,可是講真蔚万,屬性指針在哪傲胙?反璃?昵慌?有知道的小伙伴請告訴我一下 >_< !!!

struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class super_class                                        OBJC2_UNAVAILABLE;
    const char *name                                         OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;
    struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache *cache                                 OBJC2_UNAVAILABLE;
    struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */

結(jié)論

分類中可以給一個對象添加屬性,但是不能添加實例變量淮蜈,只能通過運行時關(guān)聯(lián)上去斋攀。
注意:如果不信,你可以在原始類中打印一遍吧梧田,會發(fā)現(xiàn)只能打印出添加的屬性淳蔼,打印不出變量。

二裁眯、擴展(Extension)

在分類中鹉梨,我們可以添加屬性,聲明方法穿稳,但是這些都是私有的存皂,因為你無法把擴展給導(dǎo)出去啊,這就是和category的一個區(qū)別逢艘。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末旦袋,一起剝皮案震驚了整個濱河市骤菠,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌疤孕,老刑警劉巖商乎,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異祭阀,居然都是意外死亡鹉戚,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門柬讨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來崩瓤,“玉大人袍啡,你說我怎么就攤上這事踩官。” “怎么了境输?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵蔗牡,是天一觀的道長。 經(jīng)常有香客問我嗅剖,道長辩越,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任信粮,我火速辦了婚禮黔攒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘强缘。我一直安慰自己督惰,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布旅掂。 她就那樣靜靜地躺著赏胚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪商虐。 梳的紋絲不亂的頭發(fā)上觉阅,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天,我揣著相機與錄音秘车,去河邊找鬼典勇。 笑死,一個胖子當(dāng)著我的面吹牛叮趴,可吹牛的內(nèi)容都是我干的痴柔。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼疫向,長吁一口氣:“原來是場噩夢啊……” “哼咳蔚!你這毒婦竟也來了豪嚎?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤谈火,失蹤者是張志新(化名)和其女友劉穎侈询,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體糯耍,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡扔字,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了温技。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片革为。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖舵鳞,靈堂內(nèi)的尸體忽然破棺而出震檩,到底是詐尸還是另有隱情,我是刑警寧澤蜓堕,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布抛虏,位于F島的核電站,受9級特大地震影響套才,放射性物質(zhì)發(fā)生泄漏迂猴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一背伴、第九天 我趴在偏房一處隱蔽的房頂上張望沸毁。 院中可真熱鬧,春花似錦傻寂、人聲如沸息尺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽掷倔。三九已至,卻和暖如春个绍,著一層夾襖步出監(jiān)牢的瞬間勒葱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工巴柿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留凛虽,地道東北人。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓广恢,卻偏偏與公主長得像凯旋,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,627評論 2 350

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

  • 把網(wǎng)上的一些結(jié)合自己面試時遇到的面試題總結(jié)了一下至非,以后有新的還會再加進來钠署。 1. OC 的理解與特性 OC 作為一...
    AlaricMurray閱讀 2,553評論 0 20
  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 1,690評論 0 9
  • Getting started(入口)Welcome to Training for Android develo...
    AiPuff閱讀 197評論 0 0
  • 或許是夏天快要來了的原因荒椭,天氣變得讓人感到異常悶熱谐鼎,寫作業(yè)寫得特別煩躁,根本寫不進去趣惠,效率很低狸棍。為了緩解下心...
    7e閱讀 443評論 0 3
  • 親愛的媽媽: 昨天,我得知你送咪貝上編程課的時候和周老師聊了會天味悄。你告訴周老師草戈,驚喜地看到自己的女兒越來越出色,連...
    葛瑛閱讀 209評論 2 6