iOS -Runtime method

1.先來(lái)看一下method相關(guān)的定義

typedef struct objc_method *Method;

  struct objc_method {
      SEL method_name;
      char *method_types;
      IMP method_imp;
  } 

  struct objc_method_list {
      struct objc_method_list *obsolete                        OBJC2_UNAVAILABLE;

      int method_count                                         OBJC2_UNAVAILABLE;
  #ifdef __LP64__
      int space                                                OBJC2_UNAVAILABLE;
  #endif
      /* variable length structure */
      struct objc_method method_list[1]                        OBJC2_UNAVAILABLE;
  } 

  struct objc_method_description {
      SEL name;               /**< The name of the method */
      char *types;            /**< The types of the method arguments */

  };

  struct objc_method_description_list {
      int count;
      struct objc_method_description list[1];
  };

里邊有三個(gè)類型別名,在這兒先解釋一下

SEL selector 的簡(jiǎn)寫(xiě),俗稱方法選擇器,實(shí)質(zhì)存儲(chǔ)的是方法的名稱
IMP implement 的簡(jiǎn)寫(xiě),俗稱方法實(shí)現(xiàn),看源碼得知它就是一個(gè)函數(shù)指針
Method 對(duì)上述兩者的一個(gè)包裝結(jié)構(gòu).

2.函數(shù)

method相關(guān)的函數(shù)也不是太多,下邊簡(jiǎn)單羅列說(shuō)明一下

//判斷類中是否包含某個(gè)方法的實(shí)現(xiàn)
BOOL class_respondsToSelector(Class cls, SEL sel)
//獲取類中的方法列表
Method *class_copyMethodList(Class cls, unsigned int *outCount)
//為類添加新的方法,如果方法該方法已存在則返回NO
BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)
//替換類中已有方法的實(shí)現(xiàn),如果該方法不存在添加該方法
IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types)
//獲取類中的某個(gè)實(shí)例方法(減號(hào)方法)
Method class_getInstanceMethod(Class cls, SEL name)
//獲取類中的某個(gè)類方法(加號(hào)方法)
Method class_getClassMethod(Class cls, SEL name)
//獲取類中的方法實(shí)現(xiàn)
IMP class_getMethodImplementation(Class cls, SEL name)
//獲取類中的方法的實(shí)現(xiàn),該方法的返回值類型為struct
IMP class_getMethodImplementation_stret(Class cls, SEL name)

//獲取Method中的SEL
SEL method_getName(Method m)
//獲取Method中的IMP
IMP method_getImplementation(Method m)
//獲取方法的Type字符串(包含參數(shù)類型和返回值類型)
const char *method_getTypeEncoding(Method m)
//獲取參數(shù)個(gè)數(shù)
unsigned int method_getNumberOfArguments(Method m)
//獲取返回值類型字符串
char *method_copyReturnType(Method m)
//獲取方法中第n個(gè)參數(shù)的Type
char *method_copyArgumentType(Method m, unsigned int index)
//獲取Method的描述
struct objc_method_description *method_getDescription(Method m)
//設(shè)置Method的IMP
IMP method_setImplementation(Method m, IMP imp)
//替換Method
void method_exchangeImplementations(Method m1, Method m2)

//獲取SEL的名稱
const char *sel_getName(SEL sel)
//注冊(cè)一個(gè)SEL
SEL sel_registerName(const char *str)
//判斷兩個(gè)SEL對(duì)象是否相同
BOOL sel_isEqual(SEL lhs, SEL rhs)

//通過(guò)塊創(chuàng)建函數(shù)指針,block的形式為^ReturnType(id self,參數(shù),...)
IMP imp_implementationWithBlock(id block)
//獲取IMP中的block
id imp_getBlock(IMP anImp)
//移出IMP中的block
BOOL imp_removeBlock(IMP anImp)

//調(diào)用target對(duì)象的sel方法
id objc_msgSend(id target, SEL sel, 參數(shù)列表...)
Showtime

3.下邊就來(lái)玩玩runtime API中的method相關(guān)操作

  //創(chuàng)建繼承自NSObject類的People類
  Class People = objc_allocateClassPair([NSObject class], "People", 0);
  //將People類注冊(cè)到runtime中
  objc_registerClassPair(People);
  //注冊(cè)test: 方法選擇器
  SEL sel = sel_registerName("test:");
  //函數(shù)實(shí)現(xiàn)
  IMP imp = imp_implementationWithBlock(^(id this,id args,...){
      NSLog(@"方法的調(diào)用者為 %@",this);
      NSLog(@"參數(shù)為 %@",args);
      return @"返回值測(cè)試";
  });

  //向People類中添加 test:方法;函數(shù)簽名為@@:@,
  //    第一個(gè)@表示返回值類型為id,
  //    第二個(gè)@表示的是函數(shù)的調(diào)用者類型,
  //    第三個(gè):表示 SEL
  //    第四個(gè)@表示需要一個(gè)id類型的參數(shù)
  class_addMethod(People, sel, imp, "@@:@");
  //替換People從NSObject類中繼承而來(lái)的description方法
  class_replaceMethod(People,@selector(description), imp_implementationWithBlock(^NSString*(id this,...){
      return @"我是Person類的對(duì)象";}),
      "@@:");

  //完成 [[People alloc]init];
  id p1 = objc_msgSend(objc_msgSend(People, @selector(alloc)),@selector(init));
  //調(diào)用p1的sel選擇器的方法,并傳遞@"???"作為參數(shù)
  id result = objc_msgSend(p1, sel,@"???");
  //輸出sel方法的返回值
  NSLog(@"sel 方法的返回值為 : %@",result);

  //獲取People類中實(shí)現(xiàn)的方法列表
  NSLog(@"輸出People類中實(shí)現(xiàn)的方法列表");
  unsigned int methodCount;
  Method * methods = class_copyMethodList(People, &methodCount);
  for (int i = 0; i<methodCount; i++) {
      NSLog(@"方法名稱:%s",sel_getName(method_getName(methods[i])));
      NSLog(@"方法Types:%s",method_getDescription(methods[i])->types);
  }
  free(methods);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子脐嫂,更是在濱河造成了極大的恐慌,老刑警劉巖循榆,帶你破解...
    沈念sama閱讀 212,542評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件攘须,死亡現(xiàn)場(chǎng)離奇詭異灰蛙,居然都是意外死亡胰耗,警方通過(guò)查閱死者的電腦和手機(jī)限次,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)柴灯,“玉大人卖漫,你說(shuō)我怎么就攤上這事费尽。” “怎么了懊亡?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,021評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵依啰,是天一觀的道長(zhǎng)乎串。 經(jīng)常有香客問(wèn)我店枣,道長(zhǎng),這世上最難降的妖魔是什么叹誉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,682評(píng)論 1 284
  • 正文 為了忘掉前任鸯两,我火速辦了婚禮,結(jié)果婚禮上长豁,老公的妹妹穿的比我還像新娘钧唐。我一直安慰自己,他們只是感情好匠襟,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布钝侠。 她就那樣靜靜地躺著,像睡著了一般酸舍。 火紅的嫁衣襯著肌膚如雪帅韧。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,985評(píng)論 1 291
  • 那天啃勉,我揣著相機(jī)與錄音忽舟,去河邊找鬼。 笑死淮阐,一個(gè)胖子當(dāng)著我的面吹牛叮阅,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播泣特,決...
    沈念sama閱讀 39,107評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼浩姥,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了状您?” 一聲冷哼從身側(cè)響起及刻,我...
    開(kāi)封第一講書(shū)人閱讀 37,845評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎竞阐,沒(méi)想到半個(gè)月后缴饭,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,299評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡骆莹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評(píng)論 2 327
  • 正文 我和宋清朗相戀三年颗搂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片幕垦。...
    茶點(diǎn)故事閱讀 38,747評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡丢氢,死狀恐怖傅联,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情疚察,我是刑警寧澤蒸走,帶...
    沈念sama閱讀 34,441評(píng)論 4 333
  • 正文 年R本政府宣布,位于F島的核電站貌嫡,受9級(jí)特大地震影響比驻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜岛抄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評(píng)論 3 317
  • 文/蒙蒙 一别惦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧夫椭,春花似錦掸掸、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,828評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至仁讨,卻和暖如春羽莺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背陪竿。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,069評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工禽翼, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人族跛。 一個(gè)月前我還...
    沈念sama閱讀 46,545評(píng)論 2 362
  • 正文 我出身青樓闰挡,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親礁哄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子长酗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評(píng)論 2 350

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