二級指針指向的數據結構是什么樣的权逗?

//代碼片段摘自蘋果開源的runtime代碼(objc4-208版本)
//https://opensource.apple.com/source/objc4/objc4-208/runtime/objc-class.h
struct objc_class {         
    struct objc_class *isa; 
    struct objc_class *super_class; 
    const char *name;       
    long version;
    long info;
    long instance_size;
    struct objc_ivar_list *ivars;

#if defined(Release3CompatibilityBuild)
    struct objc_method_list *methods;
#else
    struct objc_method_list **methodLists;
#endif

    struct objc_cache *cache;
    struct objc_protocol_list *protocols;
};

這是Objective-C 2.0中的類的代碼,相信做iOS開發(fā)的同學都很熟悉的了冤议。有天在查資料又看到它的時候斟薇,想到了一個好奇的問題:

methodLists 是一個二級指針,在內存中恕酸,它指向的是什么呢堪滨?(或者說,其指向的數據結構到底是怎么樣的蕊温?)

然后袱箱,我想到了下面幾個可能性:

  • methodLists 指向的是一個結構體的指針

    aP-bP-obj.png
  • methodLists 指向的是結構體數組的指針

aP-bP-objArray.png
  • methodLists 指向的是結構體指針數組
aP-bPArray.png

那么上面的可能性都是存在的嗎遏乔?為了驗證,我寫了下面的代碼進行測試发笔。

#include <stdio.h>

typedef struct {
  float version;
} method;


int main(int argc, char const *argv[]) {
  method **methodList;

  method aMethod;
  aMethod.version = 1.1;

  method bMethod;
  bMethod.version = 2.2;

  printf("開始驗證第1種可能性:aP->bP->obj\n");
  method *aMethodP = &aMethod;
  methodList = &aMethodP;

  method* currentMethod = *methodList;
  float version = currentMethod->version;
  printf("version:%0.1f\n",version);

  printf("結束驗證第1種可能性按灶。\n");

  printf("開始驗證第2種可能性:aP->bP->obj[]\n");
  method methodArray[2];
  methodArray[0] = aMethod;
  methodArray[1] = bMethod;

  *methodList = methodArray;
  for (size_t i = 0; i < 2; i++) {
    method* currentMethod = &((*methodList)[i]);
    float version = currentMethod->version;
    printf("version:%0.1f\n",version);
  }
  printf("結束驗證第2種可能性。\n");

  printf("開始驗證第3種可能性:aP->[(bP->obj)]\n");
  method* methodPointArray[2];
  methodPointArray[0]=&aMethod;
  methodPointArray[1]=&bMethod;

  methodList = &(methodPointArray[0]);
  for (size_t i = 0; i < 2; i++) {
    method* currentMethod = *(methodList+i);
    float version = currentMethod->version;
    printf("version:%0.1f\n",version);
  }
  printf("結束驗證第3種可能性筐咧。\n");

  return 0;
}

運行結果如下:

二級指針可能性運行結果.png

按照上面提出的模型所編寫的代碼可以運行通過鸯旁,這證明所說的3種可能性都存在,然而在runtime里使用的是哪種呢量蕊?

為此铺罢,特意去看了相關的代碼,得到的答案是:第三種残炮。

論據為:runtime中的class移除method的方法代碼:

//代碼片段摘自蘋果開源的runtime代碼(objc4-208版本)
//https://opensource.apple.com/source/objc4/objc4-208/runtime/objc-class.m

void class_removeMethods (Class cls, struct objc_method_list * meths)
{
    // Remove atomically.
    _objc_removeMethods (meths, &((struct objc_class *) cls)->methodLists);
    
    // Must flush when dynamically removing methods.  No need to flush
    // all the class method caches.  If cls is a meta class, though,
    // this will still flush it and any of its sub-meta classes.
    flush_caches (cls, NO); 
}
//代碼片段摘自蘋果開源的runtime代碼(objc4-208版本)
//https://opensource.apple.com/source/objc4/objc4-208/runtime/objc-runtime.m

void _objc_removeMethods (struct objc_method_list * mlist, struct objc_method_list *** list)
{
    struct objc_method_list **  ptr;
 
        // Locate list in the array 
        ptr = *list;
        while (*ptr != mlist) {
                // fix for radar # 2538790
                if ( *ptr == END_OF_METHODS_LIST ) return;
                ptr += 1;
        }
 
        // Remove this entry 
        *ptr = 0;
  
        // Left shift the following entries
        while (*(++ptr) != END_OF_METHODS_LIST)
                *(ptr-1) = *ptr;
        *(ptr-1) = 0;
}

寫在最后

那么對于標題提出的問題:『二級指針指向的數據結構是什么樣的韭赘?』,它的標準答案是什么呢势就?

答案是:沒有標準答案泉瞻,它的答案應該是結合具體的業(yè)務代碼來回答的,比如Runtime里的methodLists苞冯。

另外袖牙,在最后,不得不感嘆下:指針真是C語言的靈魂舅锄,其讓C變得何其靈活1薮铩(當然,同時也讓C變得復雜皇忿,在你不知道作者的指針意圖的時候)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末畴蹭,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子鳍烁,更是在濱河造成了極大的恐慌叨襟,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件幔荒,死亡現場離奇詭異糊闽,居然都是意外死亡,警方通過查閱死者的電腦和手機铺峭,發(fā)現死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門墓怀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來汽纠,“玉大人卫键,你說我怎么就攤上這事∈洌” “怎么了莉炉?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵钓账,是天一觀的道長。 經常有香客問我絮宁,道長梆暮,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任绍昂,我火速辦了婚禮啦粹,結果婚禮上,老公的妹妹穿的比我還像新娘窘游。我一直安慰自己唠椭,他們只是感情好,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布忍饰。 她就那樣靜靜地躺著贪嫂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪艾蓝。 梳的紋絲不亂的頭發(fā)上力崇,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機與錄音赢织,去河邊找鬼亮靴。 笑死,一個胖子當著我的面吹牛于置,可吹牛的內容都是我干的台猴。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼俱两,長吁一口氣:“原來是場噩夢啊……” “哼饱狂!你這毒婦竟也來了?” 一聲冷哼從身側響起宪彩,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤休讳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后尿孔,有當地人在樹林里發(fā)現了一具尸體俊柔,經...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年活合,在試婚紗的時候發(fā)現自己被綠了雏婶。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡白指,死狀恐怖留晚,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情告嘲,我是刑警寧澤错维,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布奖地,位于F島的核電站,受9級特大地震影響赋焕,放射性物質發(fā)生泄漏参歹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一隆判、第九天 我趴在偏房一處隱蔽的房頂上張望犬庇。 院中可真熱鬧,春花似錦侨嘀、人聲如沸械筛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽埋哟。三九已至,卻和暖如春郎汪,著一層夾襖步出監(jiān)牢的瞬間赤赊,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工煞赢, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留抛计,地道東北人。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓照筑,卻偏偏與公主長得像吹截,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子凝危,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內容