@interface Person : NSObject
{
@public
int _age;
}
@end
@implementation Person
@end
@interface Student : Person
{
@public
int _no;
}
@end
@implementation Student
@end
1. 回顧day01
欠橘,上面的代碼,如果NSObject
黍檩、Person
和Student
轉換成 C++ 的結構體是怎么樣的始锚,請寫出來瞧捌。
- 這是我們
day01
學到的最重要內(nèi)容润文,有助于我們理解很多東西 - 轉換代碼如下:
typedef struct objc_class *Class;
struct NSObject_IMPL {
Class isa;
}
struct Person_IMPL {
struct NSObject_IMPL NSObject_IVARS;
int _age;
}
struct Student_IMPL {
Struct Person_IMPL Person_IVARS;
int _no;
}
2. 在 Objective-C 中的對象殿怜,簡稱為 OC 對象头谜,有哪些?主要可以分三類
- instance 對象(實例對象)
- class 對象 (類對象)
- meta-class 對象(元類對象)
3. 從代碼的角度砖织,分別如何獲取上面的三種對象末荐?
NSObject *obj1 = [[NSObject alloc] init];
NSObject *obj2 = [[NSObject alloc] init];
NSLog(@"instance obj: %p, %p", obj1, obj2);
Class ClassObj1 = [NSObject class];
Class ClassObj2 = [obj1 class];
Class ClassObj3 = [obj2 class];
Class ClassObj4 = objc_getClass("NSObject");
Class ClassObj5 = object_getClass(obj1);
NSLog(@"class obj: %p, %p, %p, %p, %p",
ClassObj1,
ClassObj2,
ClassObj3,
ClassObj4,
ClassObj5);
Class metaClass1 = object_getClass([NSObject class]);
NSLog(@"metaClass obj: %p",
metaClass1);
輸出結果:
Demo3[4239:151141] instance obj: 0x100447e20, 0x1004463d0
Demo3[4239:151141] class obj: 0x7fff902e7118, 0x7fff902e7118, 0x7fff902e7118, 0x7fff902e7118, 0x7fff902e7118
Demo3[4239:151141] metaClass obj: 0x7fff902e70f0
4. 觀察上面的代碼甲脏,你能獲取哪些知識點或者有哪些疑問块请?從內(nèi)存占用的角度看
-
實例對象
在內(nèi)存中的地址不相同,可以得出每份實例經(jīng)過alloc
贸弥,都會有自己的獨占空間海渊,是一個全新的對象。 -
類對象
無論用哪一種方式獲得盔憨,從obj1
或者obj2
等等其他方式讯沈,最終拿到的內(nèi)存地址都是相同缺狠,說明他們共享了一個類對象
。 -
元類對象
從類對象
獲得蝴乔,說明也和實例無關驮樊,也是一個共享對象
。
5. 觀察上面的代碼挖腰,你能獲取哪些知識點或者有哪些疑問猴仑?從類對象
和元類對象
都是 Class
類型看
-
NSObject
的元類對象和類對象都在內(nèi)存中都只有一份 - 類對象和元類對象的類型相同肥哎,都是
Class
類型 -
Class
是一種結構體指針,說明類對象
和元類對象
其實擁有相同的結構
6. 觀察上面的代碼崖飘,你能獲取哪些知識點或者有哪些疑問杈女?從獲取方式的角度看
-
- (Class)class
和+ (Class)class
這兩種方式獲得的都是類對象
-
objc_getClass
獲取的也是類對象
-
Class object_getClass(id _Nullable obj)
比較復雜达椰,傳入instance對象
返回class對象
;傳入class對象
返回meta-class對象
梁沧; 傳入class對象
返回NSObject(基類)的 meta-class 對象