iOS底層原理總結(jié) - OC對象的分類
- Objective-C中的對象, 簡稱OC對象, 主要可以分為3種
-
instance
對象(實(shí)例對象) -
class
對象(類對象) -
meta-class
對象(元類對象)
-
一展蒂、instance
-
instance
對象就是通過類alloc
出來的對象, 每次調(diào)用alloc
都會產(chǎn)生新的instance
對象
NSObject *obj1 = [[NSObject alloc] init];
NSObject *obj2 = [[NSObject alloc] init];
NSLog(@"obj1 - %p", obj1); // 打印: obj1 - 0x100500e90
NSLog(@"obj2 - %p", obj2); // 打印: obj2 - 0x1005061b0
obj1
锰悼、obj2
是NSObject
的instance
對象(實(shí)例對象), 它們是不同的兩個對象箕般,分別占據(jù)著兩塊不同的內(nèi)存-
instance對象在內(nèi)存中存儲的信息包括
-
isa
指針 - 其他
成員變量
-
例如, 一個
Person
類, 繼承自NSObject
, 有一個_age
的成員變量
@interface Person: NSObject {
@public
int _age;
}
@end
@implementation Person
@end
- 創(chuàng)建
Person
類的instance
對象, 并給成員變量_age
賦值
Person *p1 = [[Person alloc] init];
p1->_age = 3
Person *p2 = [[Person alloc] init];
p2->_age = 4
- 因為
p1
和p2
是兩個alloc
創(chuàng)建的對象, 所以在內(nèi)存中分別占用一塊內(nèi)存, 類似于下圖
二曲初、class
-
class
類對象, 可以通過alloc
創(chuàng)建出instance
對象 - 有三種方式, 可以獲取一個類對象
- (Class)class
+ (Class)class
object_getClass(實(shí)例對象)
NSObject *obj1 = [[NSObject alloc] init];
NSObject *obj2 = [[NSObject alloc] init];
// - (Class)class
Class objectClass1 = [obj1 class];
Class objectClass2 = [obj2 class];
// + (Class)class
Class objectClass3 = [NSObject class];
// object_getClass(實(shí)例對象)
Class objectClass4 = object_getClass(obj1);
Class objectClass5 = object_getClass(obj2);
-
objectClass1 ~ objectClass5
都是NSObject
的class
對象(類對象) - 它們是同一個對象, 每個類在內(nèi)存中有且只有一個
class
對象, 可以通過打印內(nèi)存證明:
NSLog(@"%p %p %p %p %p",
objectClass1,
objectClass2,
objectClass3,
objectClass4,
objectClass5);
// 打印結(jié)果: 0x7fff955aa140 0x7fff955aa140 0x7fff955aa140 0x7fff955aa140 0x7fff955aa140
通過打印結(jié)果可以證明,
objectClass1 ~ objectClass5
指向這同一塊內(nèi)存地址, 即在內(nèi)存中會存在一個類的class
對象-
class對象在內(nèi)存中存儲的信息主要包括:
-
isa
指針 -
superclass
指針 - 類的
屬性
信息(@property) - 類的
對象方法
信息(instance method) - 類的
協(xié)議
信息(protocol) - 類的
成員變量
信息(ivar, 描述成員變量的類型和名字, 而不是如同實(shí)例一般具體的值) - ...
-
如下圖:
三、meta-class
- 每個類在內(nèi)存中有且只有一個
meta-class
對象 - 可以通過運(yùn)行時的
object_getClass(類對象)
方法獲取類的元類型
// Runtime API
Class objectMetaClass = object_getClass([NSObject class]);
objectMetaClass
是NSObject
的meta-class
對象(元類對象)-
meta-class
對象和class
對象的內(nèi)存結(jié)構(gòu)是一樣的颁褂,但是用途不一樣,在內(nèi)存中存儲的信息主要包括:-
isa
指針 -
superclass
指針 - 類的
類方法
信息(class method)
-
注意:
meta-class對象
和class對象
擁有相同的結(jié)構(gòu), 意思如下圖
class對象
中,類方法信息
為空,meta-class
方法中屬性信息
、對象方法信息
惨缆、協(xié)議信息
坯墨、成員變量信息
為空
注意:
- (Class)class
和+ (Class)class
方法只能獲取class對象
, 不能獲取meta-class對象
meta-class對象
只能通過Runtime
的object_getClass(類對象)
獲取
- 可以通過
Runtime
的class_isMetaClass(對象)
函數(shù), 來判斷對象是否是元類型
Class objectClass = [NSObject class];
NSLog(@"%d", class_isMetaClass(objectClass)); // 打印: 0
Class objectMetaClass = object_getClass([NSString class]);
NSLog(@"%d", class_isMetaClass(objectMetaClass)); // 打印: 1
- 下面是
objc_getClass
捣染、object_getClass
停巷、- (Class)class畔勤、+ (Class)class
的區(qū)別
1.Class objc_getClass(const char *aClassName)
1> 傳入字符串類名
2> 返回對應(yīng)的類對象
2.Class object_getClass(id obj)
1> 傳入的obj可能是instance對象、class對象式曲、meta-class對象
2> 返回值
a) 如果是instance對象缸榛,返回class對象
b) 如果是class對象内颗,返回meta-class對象
c) 如果是meta-class對象,返回NSObject(基類)的meta-class對象
3.- (Class)class恨溜、+ (Class)class
1> 返回的就是類對象
- (Class) {
return self->isa;
}
+ (Class) {
return self;
}
參考文章:原文鏈接