NSObject相關

2021-02-14 iOS小菜鳥
NSObject知識點

一個NSObject對象佔用多少內存?

🌰
NSObject *object = [[NSObject alloc] init];
//獲取類對象所佔有內存大小
NSLog(@"%zu", class_getInstanceSize([object class]));
//獲取NSObject實例對象所佔用內存大小
NSLog(@"%zu", malloc_size((__bridge void *)object)); //16

class_getInstanceSize是獲取類對象在內存中的大小是8個字節,而malloc_size是獲取實例對象在內存中的大小是16個字節,那究竟一個NSObject在內存中是佔用8個字節還是16個字節呢,我們來繼續深入了解。

類對象大小
struct NSObject_IMPL {
   Class isa;
};

size_t class_getInstanceSize(Class cls)
{
    return cls->alignedInstanceSize();
}
// Class's ivar size rounded up to a pointer-size boundary.
uint32_t alignedInstanceSize() const {
    return word_align(unalignedInstanceSize());
}

將代碼轉化為cpp源碼,可以看到類對象底層實現其實就是一個簡單的結構體,包含一個isa的類對象指針,在64位系統下,一個指針佔用內存就是8個字節!class_getInstanceSize源碼底層是獲取類對象中變量所佔用的內存大小,因為類對象結構體中只有一個isa指針變量,所以一個類對象佔用內存大小是8個字節。所以類的本質是一個佔用內存八個字節的結構體!實例對象大小
inline size_t instanceSize(size_t extraBytes) const {
  size_t size = alignedInstanceSize() + extraBytes;
  // CF requires all objects be at least 16 bytes.
  if (size < 16) size = 16;
    return size;
}

當我們使用alloc方法生成一個對象底層會調用到instanceSize方法,如果我們的對象中變量所佔用的內存大小小於16個字節的話,系統默認會幫我們將對象內存大小擴充到16個字節,而實際中對象所使用到的內存只有8個字節而已!

🌰

@interface JZPerson : NSObject
{
    @public
    int age;
    int num;
}
@end
@implementation JZPerson
@end

@interface JZBoy : JZPerson
{
    @public
    int sex;
    int sex2;
}
@end
@implementation JZBoy
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        JZBoy *boy = [[JZBoy alloc] init];
        NSLog(@"%zu", class_getInstanceSize([JZBoy class]));
        NSLog(@"%zu", malloc_size((__bridge void *)boy));
    }
    return 0;
}

第一行輸出結果是24,這裡涉及到內存對齊問題,結構體的大小必須是最大成員內存大小的倍數,本來這裡的變量佔用內存大小只有20個字節,但是系統會幫我們分配24個字節,即8的整數倍。第二行輸出的結果是32,這裡到底為什麼是32,我們要繼續分析alloc方法的底層實現代碼!
_class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone)
{
    void *bytes;
    size_t size;

    //獲取對象中變量實際佔用內存大小,extraBytes一般為0
    size = cls->alignedInstanceSize() + extraBytes;

    // CF requires all objects be at least 16 bytes.
    if (size < 16) size = 16;
    //這個方法蘋果幫我們的內存大小做了處理
    bytes = calloc(1, size);
    return objc_constructInstance(cls, bytes);
}

calloc(size_t num_items, size_t size) {
  #define NANO_MAX_SIZE   256 /* Buckets sized {16, 32, 48, ..., 256} */
}

我們下載了malloc源碼,可以看到蘋果底層是以桶的概念來分配內存的,而且分配對象內存大小是以16位元組的整數倍來進行分配的!

小結

類的本質其實是結構體來實現的,佔用的內存大小為一個isa的類指針大小!實例對象佔用內存大小其實是按照16的整數倍來進行內存大小的分配,以空間換時間,提高系統的運行效率!

對象的isa指針指向哪裡?

🌰
#   define ISA_MASK        0x00007ffffffffff8ULL
@interface Person : NSObject
{
    @public
    int _age;
}
@property (nonatomic, assign) int height;
@end
@implementation Person
@end
//為了獲取類對象的isa指針地址
struct NSObject_Class {
    Class isa;
    Class superclass;
};
int main(int argc, const char * argv[]) {
    @autoreleasepool { 
        //instance 實例對象
        Person *personObject = [[Person alloc] init];
        //class 類對象
        Class personClass = [personObject class];
        //meta-class 元類對象
        Class personMetaClass = object_getClass(personClass);
        struct NSObject_Class *objectClass = (__bridge struct NSObject_Class *)personClass;
        struct NSObject_Class *metaClass = (__bridge struct NSObject_Class *)personMetaClass;
    }
    return 0;
}

OC底層實現源碼其實就是將對象的isa指針&ISA_MASK就得到了父類的地址。

實例對象personObject的isa&ISA_MASK = personClass類對象的地址;類對象personClass的isa&ISA_MASK = personMetaClass元類對象的地址;
這個就是驗證的結果:
(lldb) p/x personObject->isa
(Class) $0 = 0x001d8001000011d9 Person
(lldb) p/x personClass
(Class) $1 = 0x00000001000011d8 Person
(lldb) p/x 0x001d8001000011d9 & 0x00007ffffffffff8ULL
(unsigned long long) $2 = 0x00000001000011d8
(lldb) p/x objectClass->isa
(Class) $3 = 0x00000001000011b0
(lldb) p/x personMetaClass
(Class) $4 = 0x00000001000011b0
(lldb) p/x 0x00000001000011b0 & 0x00007ffffffffff8ULL
(unsigned long long) $5 = 0x00000001000011b0

小結

class對象的isa指向meta-class對象;meta-class對象的isa指向基類的meta-class對象;

OC的類信息存放在哪裡?

🌰
@interface Person : NSObject<NSCoding>
{
    @public
    int _age;
}
@property (nonatomic, assign) int height;
@end

@implementation Person
- (void)name {
    NSLog(@"name");
}
+ (void)eat {
    NSLog(@"eat");
}
@end

通過底層源碼來窺探實例對象變量,方法,類方法等信息的存儲情況:

小結

對象方法、屬性、成員變量、協議信息,存放在class對象中;isa、superclass總結

meta-class的isa指向基類的meta-classclass的superclass指向父類的class,如果沒有父類,superclass指針為nilmeta-class的superclass指向父類的meta-class,基類的meta-class的superclass指向基類的類對象classinstance調用對象方法的軌跡isa找到class,方法不存在,就通過superclass找父類class調用類方法的軌跡isa找meta-class,方法不存在,就通過superclass找父類

相關焦點

  • 相關部門,相關信息,與「相關」相關的英語單詞,你分清了嗎?
    (緊密相關的,切題的,有重大意義的)牛津字典英文翻譯如下:1.closely connected with the subject you are discussing下面舉幾個例子進一步說明一下:一)相關部門(relevant department & related department) 比如,某棟大樓突然起火了,這時,需要趕緊聯繫相關部門 relevant departments(120,119,110)eg. this
  • SPSS分析技術:Pearson相關、Spearman相關及Kendall相關
    可以通過下面的思維導圖幫助記憶:常用的相關性分析包括:皮爾遜(Pearson)相關、斯皮爾曼(Spearman)相關、肯德爾(Kendall)相關和偏相關。下面介紹前三種相關分析技術,並用實際案例說明如何用SPSS使用這三種相關性分析技術。三種相關性檢驗技術,Pearson相關性的精確度最高,但對原始數據的要求最高。
  • 自相關與偏自相關的簡單介紹
    初學者要理解時間序列預測中自相關和偏自相關之間的差別很困難。在本教程中,您將發現如何使用Python來計算和繪製自相關圖和偏自相關圖。完成本教程後,您將知道:讓我們開始吧。每日最低氣溫數據集該數據集描述了澳大利亞墨爾本市10年(1981 – 1990年)的最低每日氣溫。
  • 自相關
    自相關目錄1 什麼是自相關1.1 自相關概念1.2 自相關產生的原因1.3 自相關表現形式2 自相關後果3自相關檢驗4 自相關補救4.1 廣義差分法4.2 Cochrane—Orcutt迭代法4.3 差分法
  • 除了簡單相關分析,我還會典型相關分析
    言歸正傳,接下來帶你學習典型相關分析和SPSS的操作。理論介紹:在一元統計分析中,研究兩個隨機變量之間的線性相關關係,可以用簡單相關係數;研究一個隨機變量與多個隨機變量之間的線性相關關係,可用復相關係數。但如果要研究兩組變量的相關關係時,這些統計方法就無能為力了。
  • 三大相關係數簡介及其在R中的相關函數
    概率統計學習中最常見的是Pearson相關係數,其取值範圍是[-1,1],當取值為0時表示不(線性)相關,取值為[-1,0)表示負相關,取值為(0,1]表示正相關。相關係數絕對值越接近於1,兩個變量間(線性)相關性越強。
  • 相關成本與非相關成本(relevant cost and irrelevant cost)
    相關成本與非相關成本(relevant cost and irrelevant cost)     成本按其發生是否與決策項目相關的分類。相關成本是指與制定決策方案有關的聯影響的成本,例如當期是否接受一批訂貨 ,生產該批訂貨需要花費的各種成本,即為相關成本。
  • 典型相關分析
    在一元統計分析中,兩個隨機變量X,Y之間的線性相關關係可用簡單相關係數描述;一個隨機變量Y和一組隨機變量X之間的線性相關關係可用復相關係數描述;固定其他變量Xj(j≠i)條件下,Y與某個Xi之間的相關關係可用偏相關係數描述[1]。      而在實際應用中,還會遇到研究兩組隨機變量X (X1,X2,X2,...,Xp)和Y (Y1,Y2,Y3,...
  • 【相關分析】概述
    進一步,統計分析如果按照相關的形態來說,可分為線性相關和非線性相關(曲線相關);如果按照相關的方向來分,可分為正相關和負相關,等等。詳細見下面的圖形。描述兩個變量是否有相關性,常見的方式有:可視化相關圖(典型的如散點圖和列聯表等等)、相關係數、統計顯著性。如果用可視化的方式來呈現各種相關性,常見有如下散點圖。對於不同的因素類型,採用的相關性分析方法也不相同。
  • 模型研究4-相關係數問題(皮爾遜相關係數法)
    本期:相關係數問題研究如果有兩個變量:X、Y,最終計算出的相關係數的含義可以有如下理解:當相關係數為
  • 事件相關電位
    二十世紀六十年代,Sutton提出了事件相關電位的概念,通過平均疊加技術從頭顱表面記錄大腦誘發電位來反映認知過程中大腦的神經電生理改變,因為事件相關電位與認知過程有密切關係,故被認為是「窺視」心理活動的「窗口」。神經電生理技術的發展,為研究大腦認知活動過程提供了新的方法和途徑。經典的ERP主要成分包括P1、N1、P2、N2、P3,其中前三種稱為外源性成分,而後兩種稱為內源性成分。
  • 相關部門不公開房屋拆遷相關信息,被徵收人是否有權查看相關文件
    在現實生活當中,經常碰到這種類似情況:被徵收人在不知情,房屋就被一紙通知,要拆遷的情況,因此,在徵地拆遷過程中,作為被徵收人,我們是否有權查看相關的徵地拆遷文件呢?答案是肯定的。被徵收人有權查看相關的徵地拆遷文件根據《中華人民共和國政府信息公開條例》的規定,行政機關應當及時
  • 與cold相關的短語
    今天我們來學習幾個與「cold」相關的短語。1. cold-blooded 冷血的;冷酷的例句:The real world is so different from what it is in my imagination. But it is surely a real world, a cold-blooded world.
  • 皮爾遜積差相關/斯皮爾曼等級相關的含義和使用條件
    一,皮爾遜積差相關積差相關通常是用來考察連續數據之間的相關性。
  • 自相關和互相關函數計算方法總結及心得體會
    x(t),y(t)在任意兩個不同時刻t1,t2的取值之間的相關程度,自相關函數是描述隨機信號x(t)在任意兩個不同時刻t1,t2的取值之間的相關程度。事實上,在圖象處理中,自相關和互相關函數的定義如下:設原函數是f(t),則自相關函數定義為R(u)=f(t)*f(-t),其中*表示卷積;設兩個函數分別是f(t)和g(t),則互相關函數定義為R(u)=f(t)*g(-t),它反映的是兩個函數在不同的相對位置上互相匹配的程度。那麼,如何在matlab中實現這兩個相關並用圖像顯示出來呢?
  • 離婚相關詞彙
    請看相關報導:以下為大家總結一些跟離婚相關的詞彙:separate 分居split up 分手/離婚marital discord 婚姻不和marital breakdown 婚姻關係的破裂domestic violence(abuse) 家暴extramarital affair 婚外情adultery
  • Pearson(皮爾遜)相關係數
    相關係數:考察兩個事物(在數據裡我們稱之為變量)之間的相關程度。如果有兩個變量:X、Y,最終計算出的相關係數的含義可以有如下理解:(1)、當相關係數為0時,X和Y兩變量無關係。(2)、當X的值增大(減小),Y值增大(減小),兩個變量為正相關,相關係數在0.00與1.00之間。
  • SPSS中的「相關」分析
    SPSS中有多個模塊中的多個指標反映變量間相關或關聯程度,現簡單介紹如下:一、相關分析有關統計量及意義(一)兩個計量資料的相關分析1、Pearson 相關係數最常用的相關係數,又稱積差相關係數,該係數的計算和檢驗為參數方法
  • 「back」的相關短語
    相關閱讀「Bone」的相關表達「Ear」的相關英文表達各種head和brain「Sweet」的習慣用語(中國日報網英語點津 Rosy 編輯)
  • SPSS: Pearson相關分析
    ☆Variables(變量)列表,選擇2個及以上進行雙變量相關分析變量,本例為x1(髂前上棘間徑)、x2(髂脊間徑)、x3(恥骶外徑)、x4(坐骨節間徑)。☆Correlation Coefficients(相關係數)。□Pearson(Pearson相關係數),又稱積矩相關係數,適用於連續分布或正態分布變量,本例選擇此項。