method 詳解

定義

先來看一下method相關的定義

  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];
  };

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

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

method相關的函數(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)
  //替換類中已有方法的實現(xiàn),如果該方法不存在添加該方法
  IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types) 
  //獲取類中的某個實例方法(減號方法)
  Method class_getInstanceMethod(Class cls, SEL name)
  //獲取類中的某個類方法(加號方法)
  Method class_getClassMethod(Class cls, SEL name)
  //獲取類中的方法實現(xiàn)
  IMP class_getMethodImplementation(Class cls, SEL name)
  //獲取類中的方法的實現(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ù)個數(shù)
  unsigned int method_getNumberOfArguments(Method m)
  //獲取返回值類型字符串
  char *method_copyReturnType(Method m)
  //獲取方法中第n個參數(shù)的Type
  char *method_copyArgumentType(Method m, unsigned int index)
  //獲取Method的描述
  struct objc_method_description *method_getDescription(Method m)
  //設置Method的IMP
  IMP method_setImplementation(Method m, IMP imp) 
  //替換Method
  void method_exchangeImplementations(Method m1, Method m2)

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

  //通過塊創(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對象的sel方法
  id objc_msgSend(id target, SEL sel, 參數(shù)列表...)
Showtime

下邊就來玩玩runtime API中的method相關操作

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

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

  //完成 [[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類中實現(xiàn)的方法列表
  NSLog(@"輸出People類中實現(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);

轉(zhuǎn)載自:這里

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末褐墅,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌翼闹,老刑警劉巖传黄,帶你破解...
    沈念sama閱讀 216,651評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件坤塞,死亡現(xiàn)場離奇詭異程癌,居然都是意外死亡斟览,警方通過查閱死者的電腦和手機璧诵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,468評論 3 392
  • 文/潘曉璐 我一進店門汰蜘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人之宿,你說我怎么就攤上這事族操。” “怎么了澈缺?”我有些...
    開封第一講書人閱讀 162,931評論 0 353
  • 文/不壞的土叔 我叫張陵坪创,是天一觀的道長。 經(jīng)常有香客問我姐赡,道長莱预,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,218評論 1 292
  • 正文 為了忘掉前任项滑,我火速辦了婚禮依沮,結果婚禮上,老公的妹妹穿的比我還像新娘枪狂。我一直安慰自己危喉,他們只是感情好,可當我...
    茶點故事閱讀 67,234評論 6 388
  • 文/花漫 我一把揭開白布州疾。 她就那樣靜靜地躺著辜限,像睡著了一般。 火紅的嫁衣襯著肌膚如雪严蓖。 梳的紋絲不亂的頭發(fā)上薄嫡,一...
    開封第一講書人閱讀 51,198評論 1 299
  • 那天氧急,我揣著相機與錄音,去河邊找鬼毫深。 笑死吩坝,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的哑蔫。 我是一名探鬼主播钉寝,決...
    沈念sama閱讀 40,084評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼闸迷!你這毒婦竟也來了嵌纲?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,926評論 0 274
  • 序言:老撾萬榮一對情侶失蹤稿黍,失蹤者是張志新(化名)和其女友劉穎疹瘦,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體巡球,經(jīng)...
    沈念sama閱讀 45,341評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡言沐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,563評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了酣栈。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片险胰。...
    茶點故事閱讀 39,731評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖矿筝,靈堂內(nèi)的尸體忽然破棺而出起便,到底是詐尸還是另有隱情,我是刑警寧澤窖维,帶...
    沈念sama閱讀 35,430評論 5 343
  • 正文 年R本政府宣布榆综,位于F島的核電站,受9級特大地震影響铸史,放射性物質(zhì)發(fā)生泄漏鼻疮。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,036評論 3 326
  • 文/蒙蒙 一琳轿、第九天 我趴在偏房一處隱蔽的房頂上張望判沟。 院中可真熱鬧,春花似錦崭篡、人聲如沸挪哄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,676評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽迹炼。三九已至,卻和暖如春颠毙,著一層夾襖步出監(jiān)牢的瞬間斯入,已是汗流浹背拿霉。 一陣腳步聲響...
    開封第一講書人閱讀 32,829評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留咱扣,地道東北人。 一個月前我還...
    沈念sama閱讀 47,743評論 2 368
  • 正文 我出身青樓涵防,卻偏偏與公主長得像闹伪,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子壮池,可洞房花燭夜當晚...
    茶點故事閱讀 44,629評論 2 354

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