用Objective-C 等面向?qū)ο缶幊陶Z言時(shí),“對(duì)象”(object) 就是“基本構(gòu)造單元”(building block)翻翩,開發(fā)者可以通過對(duì)象來存儲(chǔ)并傳遞數(shù)據(jù)都许。
Objective-C 中的對(duì)象總的來說可以分為兩種:類對(duì)象和實(shí)例對(duì)象稻薇。在運(yùn)行期程序庫的頭文件中,
實(shí)例對(duì)象的定義是這樣的:
struct objc_object {
Class isa ;
};·
類對(duì)象的定義是這樣的:
typedef struct objc_class *Class;
struct objc_class {
Class isa;
Class super_class ;
...
}
可以看出梭稚,不管是實(shí)例對(duì)象還是類對(duì)象都有一個(gè) isa 成員變量颖低,
- 實(shí)例對(duì)象中的 isa 指向類結(jié)構(gòu)稱作 class(普通的),class 結(jié)構(gòu)存儲(chǔ)類的普通成員變量與普通成員方法(-開頭的方法)
- 類對(duì)象中的 isa 指向類結(jié)構(gòu)被稱作 metaclass 弧烤, metaclass 存儲(chǔ)類的類成員變量與類成員方法(+開頭的方法)
??注意??:OC語法里面忱屑,并不存在類成員變量這個(gè)概念。雖然 @property 中可以添加 class 描述暇昂,但是并不會(huì)生成類成員變量莺戒。
常用API
獲取變量信息
在JSON轉(zhuǎn)Model 中需要獲取對(duì)象的所有屬性:
unsigned int count;
objc_property_t *properties = class_copyPropertyList([self class], &count);
for(int i = 0; i < count; i++) {
objc_property_t property = properties[i];
NSLog(@"name:%s attributes:%s",property_getName(property),property_getAttributes(property));
}
free(properties);
獲取到的只是當(dāng)前類的屬性列表,如果需要獲取父類的需要自行向上遍歷急波。
上面獲取到的只是對(duì)象的屬性列表从铲,如果想要獲取對(duì)象的成員列表,
unsigned int count;
Ivar *ivars = class_copyIvarList([self class], &count);
for(int i = 0; i < count; i++) {
Ivar ivar = ivars[i];
const char *ivarName = ivar_getName(ivar);
const char *ivarType = ivar_getTypeEncoding(ivar);
NSLog(@"實(shí)例變量名為:%s 字符串類型為:%s", ivarName, ivarType);
}
free(ivars);
除了獲取成員變量列表的澄暮,還有通過指定名字獲取變量信息的方法:
Ivar _Nullable
class_getInstanceVariable(Class _Nullable cls, const char * _Nonnull name)
OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
// 由于在OC語法里面名段,并不存在類變量這個(gè)概念,所以泣懊,這個(gè)方法并沒有什么用伸辟,
Ivar _Nullable
class_getClassVariable(Class _Nullable cls, const char * _Nonnull name)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
獲取方法信息
除了獲取變量信息,還能會(huì)獲取到方法列表
unsigned int methodCount =0;
Method* methodList = class_copyMethodList([self class],&methodCount);
for(int i = 0; i < methodCount; i++) {
Method temp = methodList[i];
const char* name_s =sel_getName(method_getName(temp));
int arguments = method_getNumberOfArguments(temp);
const char* encoding =method_getTypeEncoding(temp);
NSLog(@"方法名:%@,參數(shù)個(gè)數(shù):%d,編碼方式:%@",[NSString stringWithUTF8String:name_s],
arguments,
[NSString stringWithUTF8String:encoding]);
}
free(methodList);
這里的方法就可以分實(shí)例方法和類方法馍刮,關(guān)鍵在于 class_copyMethodList
的對(duì)象信夫,如果換成下面的方式,獲取到的就是類方法列表
// 獲取到的是 metaclass
Class cls = object_getClass([self class]);
Method* methodList = class_copyMethodList(cls,&methodCount);
對(duì)于 [self class] & object_getClass(self)
的區(qū)別:
self 為實(shí)例對(duì)象 | self 為類對(duì)象 | |
---|---|---|
[self class] | 類對(duì)象(等價(jià)于object_getClass) | 類對(duì)象(自身) |
object_getClass(self) | 類對(duì)象 | 元類 |