一、OC的本質(zhì)
我們平時編寫的Objective-C代碼,底層實現(xiàn)其實都是C\C++代碼
所以O(shè)bjective-C的面向?qū)ο蠖际腔贑\C++的數(shù)據(jù)結(jié)構(gòu)實現(xiàn)的
Objective-C的對象、類主要是基于C\C++的結(jié)構(gòu)體實現(xiàn)的
如何將Objective-C代碼轉(zhuǎn)換為C\C++代碼?
在終端輸入:xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc OC源文件 -o 輸出的cpp文件
例如:xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main.cpp
二、一個NSObject對象占用多少內(nèi)存?
系統(tǒng)分配了16個字節(jié)給NSObject對象(通過malloc_size函數(shù)獲得系統(tǒng)實際分配的內(nèi)存大小)
但NSObject對象內(nèi)部只使用了8個字節(jié)的空間(64位環(huán)境下,可以通過class_getInstanceSize函數(shù)獲得)
NSObject *obj = [[NSObject alloc] init];
// 獲得NSObject實例對象的成員變量所占用的大?。?
NSLog(@"%zd", class_getInstanceSize([NSObject class]));
// 獲得obj指針所指向內(nèi)存的大小:16
NSLog(@"%zd", malloc_Size((__bridge const void *)obj));
// C++代碼,內(nèi)部只有一個成員變量isa指針,所以只占用8字節(jié)
struct NSObject_IMPL {
Class isa;
};
// runtime底層源碼,size最小為16
size_t instanceSize(size_t extraBytes) {
size_t size = alignedInstanceSize() + extraBytes;
// CF requires all objects be at least 16 bytes.
if (size < 16) size = 16;
return size;
}
三、一個Person對象、一個Student對象占用多少內(nèi)存空間?
@interface Person : NSObject {
int _age;
}
@interface Student : Person {
int _no;
}
// C++代碼
struct NSObject_IMPL {
Class isa;
};
struct Person_IMPL {
struct NSObject_IMPL NSObject_IVARS; // 8
int _age; // 4
}; // 16 內(nèi)存對齊:結(jié)構(gòu)體的大小必須是最大成員大小的倍數(shù)
struct Student_IMPL {
struct Person_IMPL Person_IVARS; // 16,有4個字節(jié)是空的正好給_no使用
int _no; // 4
}; // 16
// runtime底層源碼,size最小為16
size_t instanceSize(size_t extraBytes) {
size_t size = alignedInstanceSize() + extraBytes;
// CF requires all objects be at least 16 bytes.
if (size < 16) size = 16;
return size;
}
1、一個Person對象占用16個字節(jié):isa占用8個字節(jié),_age占用4個字節(jié),8 + 4 < 16,所以取16
2、一個Student對象占用16個字節(jié):isa占用8個字節(jié),父類的_age占用4個字節(jié),_no占用4個字節(jié),8 + 4 + 4 = 16字節(jié)
3、內(nèi)存對齊
計算結(jié)構(gòu)體的大小的內(nèi)存對齊:結(jié)構(gòu)體的大小必須是最大成員大小的倍數(shù)
系統(tǒng)分配內(nèi)存的內(nèi)存對齊方式:16的倍數(shù)
四、OC對象
OC對象有instance對象(實例對象)、class對象(類對象)、meta-class對象(元類對象),class對象、meta-class對象的本質(zhì)結(jié)構(gòu)都是struct objc_class
//instance對象(實例對象)
NSObject *object1 = [[NSObject alloc] init];
NSObject *object2 = [[NSObject alloc] init];
//class對象(類對象)
//class方法返回的一直是class對象(類對象)
Class objectClass1 = [object1 class];
Class objectClass2 = [object2 class];
Class objectClass3 = object_getClass(object1);
Class objectClass4 = object_getClass(object2);
Class objectClass5 = [NSObject class];
//meta-class對象(元類對象)
//將類對象當做參數(shù)傳入,獲得元類對象
Class metaClass = object_getClass(objectClass5);
NSLog(@"metaClass - %p", metaClass);
1、instance對象(實例對象)
instance對象就是通過類alloc出來的對象,每次調(diào)用alloc都會產(chǎn)生新的instance對象
instance對象在內(nèi)存中存儲的信息包括:
(1)isa指針
(2)其他成員變量
2、class對象(類對象)
每個類在內(nèi)存中有且只有一個class對象
類對象在內(nèi)存中存儲的信息主要包括:
(1)isa指針
(2)superclass指針
(3)類的屬性信息(@property)、類的對象方法信息(instance method)
(4)類的協(xié)議信息(protocol)、類的成員變量信息(ivar)
3、meta-class對象(元類對象)
每個類在內(nèi)存中有且只有一個meta-class對象
meta-class對象和class對象的內(nèi)存結(jié)構(gòu)是一樣的,但是用途不一樣
在內(nèi)存中存儲的信息主要包括:
(1)isa指針
(2)superclass指針
(3)類的類方法信息(class method)
五、從源碼查看struct objc_class結(jié)構(gòu)
struct objc_class {
Class isa;
Class superclass;
cache_t cache; // 方法緩存
class_data_bits_t bits; // 用于獲取具體的類信息
};
// bits & FAST_DATA_MASK
struct class_rw_t {
uint32_t flags;
uint32_t version;
const class_ro_t *ro;
method_list_t * methods; // 方法列表
property_list_t *properties; // 屬性列表
const protocol_list_t * protocols; // 協(xié)議列表
Class firstSubclass;
Class nextSiblingClass;
char *demangledName;
};
struct class_ro_t {
uint32_t flags;
uint32_t instanceStart;
uint32_t instanceSize; // instance對象占用的內(nèi)存空間
#ifdef __LP64__
uint32_t reserved;
#endif
const uint8_t * ivarLayout;
const char * name; // 類名
method_list_t * baseMethodList;
protocol_list_t * baseProtocols;
const ivar_list_t * ivars; // 成員變量列表
const uint8_t * weakIvarLayout;
property_list_t *baseProperties;
};
六、對象的isa指針和superclass指針指向哪里?

1、isa指針
instance對象的isa指針指向class對象
class對象的isa指針指向meta-class對象
meta-class對象的isa指針指向基類的meta-class對象
2、superclass指針
class對象的superclass指針指向父類的class對象
如果沒有父類,superclass指針為nil
meta-class對象的superclass指針指向父類的meta-class對象
基類的meta-class的superclass指針指向基類的class對象
蘋果源碼:opensource.apple.com/tarballs
objc4源碼下載:https://opensource.apple.com/tarballs/objc4/