iOS-在子類中重寫及調(diào)用父類私有方法

我們平時(shí)在使用三方時(shí)會(huì)比較喜歡根據(jù)自己的意愿去封裝一下三方,一般都會(huì)繼承三方創(chuàng)建一些子類矫限,用于對(duì)應(yīng)不同的需求法绵。有時(shí)三方會(huì)給我們留出接口供我們使用凭戴,但有時(shí)候并沒有涧狮。如果我們?nèi)ソo三方直接擴(kuò)充這些接口是不友好的,特別是CocoaPods上的三方么夫,所以一般我們會(huì)在子類里重寫三方的方法者冤。

三方中在.h中聲明的方法比較好重寫,直接在子類里重寫方法档痪,如果需要重調(diào)父類原有方法可以用super直接調(diào)用涉枫。而一些私有方法并沒有在.h中聲明,這時(shí)我們也可以直接重寫父類方法钞它,但是相對(duì)于想要重調(diào)父類方法,就不能用super直接調(diào)用來(lái)實(shí)現(xiàn)。這里super只是一個(gè)編譯器修飾符遭垛,是一個(gè)指向父類標(biāo)志尼桶,并不是對(duì)象的父類實(shí)例。所以你再用super調(diào)用父類的私有方法是沒有作用的锯仪。這時(shí)我們有幾種選擇可以幫我們實(shí)現(xiàn)父類私有方法的調(diào)用泵督。

首先可以用Method Swizzling(方法交換)來(lái)幫我們實(shí)現(xiàn),但是我并不喜歡使用這個(gè)方法庶喜,因?yàn)榇朔椒〞?huì)引起全局的方法指針交換小腊,多人開發(fā)中如果沒有交流好很容易出現(xiàn)一些紕漏等問(wèn)題,所以這里我就不具體介紹此方法了久窟。

第二種方法是我們可以利用runtime的消息發(fā)送機(jī)制秩冈,為我們的對(duì)象調(diào)用其父類的私有方法。主要用到objc_msgSendSuper方法斥扛,但是直接調(diào)用是不安全的入问,因?yàn)槟悴荒艽_定父類是否含有這個(gè)方法,因?yàn)槿揭部赡苓M(jìn)行升級(jí)等操作稀颁,所以調(diào)用之前需要判斷父類是否含有此方法芬失,舉個(gè)例子,代碼如下:

// 判斷一個(gè)父類是否包含某個(gè)方法(包含私有方法)
- (BOOL)lj_containsSuperMethod:(NSString *)methodName {
   
  unsigned int outCount = 0;
  Method *methods = class_copyMethodList([SuperClass class], &outCount);
  
  for (int i = 0; i < outCount; i ++) {
      Method method = methods[i];
      SEL methodNameSEL = method_getName(method);
      if ([methodName isEqualToString:NSStringFromSelector(methodNameSEL)]) {
          free(methods);
          return YES;
      }
  }
  
  free(methods);
  return NO;
}

這個(gè)方法是利用遍歷父類中的所有方法來(lái)判斷是否包含某一方法匾灶,這樣做其實(shí)也有一定的弊端棱烂,比如當(dāng)這個(gè)父類方法很多時(shí),而你又需要頻繁調(diào)用此方法時(shí)就會(huì)引起不必要的消耗阶女。如果父類包含此方法就直接利用objc_msgSendSuper發(fā)送消息就可以了颊糜,需要聲明#import <objc/message.h>。例子代碼如下:

- (void)privateMethod {
    if ([self lj_containsSuperMethod:@"privateMethod"]) {
        struct objc_super super_obj;
        super_obj.receiver = self;
        super_obj.super_class = [SuperClass class];
        objc_msgSendSuper(&super_obj, sel_registerName("privateMethod"));
    }
}

這里調(diào)用objc_msgSendSuper方法需要將ENABLE_STRICT_OBJC_MSGSEND設(shè)置為NO张肾。

第三種是先獲取父類方法芭析,然后利用構(gòu)建的方式來(lái)調(diào)用。判斷父類是否包含此方法是根據(jù)構(gòu)建出來(lái)的方法是否存在來(lái)判斷的吞瞪,相比于上一個(gè)方法減少了遍歷的過(guò)程馁启。例子代碼如下:

- (void)privateMethod {
    Method method = class_getInstanceMethod([SuperClass class], sel_registerName("privateMethod"));
    void (*super_func)(id,SEL) = (void *)method_getImplementation(method);
    if (super_func) super_func(self, sel_registerName("privateMethod"));
}  

if (super_func) 是判斷父類是否包含的此方法,如果含有此方法則調(diào)用芍秆,否則不調(diào)用惯疙。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市妖啥,隨后出現(xiàn)的幾起案子霉颠,更是在濱河造成了極大的恐慌,老刑警劉巖荆虱,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蒿偎,死亡現(xiàn)場(chǎng)離奇詭異朽们,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)诉位,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門骑脱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人苍糠,你說(shuō)我怎么就攤上這事叁丧。” “怎么了岳瞭?”我有些...
    開封第一講書人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵拥娄,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我瞳筏,道長(zhǎng)稚瘾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任乏矾,我火速辦了婚禮孟抗,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘钻心。我一直安慰自己凄硼,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開白布捷沸。 她就那樣靜靜地躺著摊沉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪痒给。 梳的紋絲不亂的頭發(fā)上说墨,一...
    開封第一講書人閱讀 49,036評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音苍柏,去河邊找鬼尼斧。 笑死,一個(gè)胖子當(dāng)著我的面吹牛试吁,可吹牛的內(nèi)容都是我干的棺棵。 我是一名探鬼主播,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼熄捍,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼烛恤!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起余耽,我...
    開封第一講書人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤缚柏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后碟贾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體币喧,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡轨域,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了杀餐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片疙挺。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖怜浅,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蔬崩,我是刑警寧澤恶座,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站沥阳,受9級(jí)特大地震影響跨琳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜桐罕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一脉让、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧功炮,春花似錦溅潜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至嫁怀,卻和暖如春设捐,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背塘淑。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工萝招, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人存捺。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓槐沼,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親召噩。 傳聞我的和親對(duì)象是個(gè)殘疾皇子母赵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

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