Objective-C:對象

用Objective-C 等面向?qū)ο缶幊陶Z言時(shí),“對象”(object) 就是“基本構(gòu)造單元”(building block),開發(fā)者可以通過對象來存儲并傳遞數(shù)據(jù)。

Objective-C 中的對象總的來說可以分為兩種:類對象和實(shí)例對象。在運(yùn)行期程序庫的頭文件中,

實(shí)例對象的定義是這樣的:

struct objc_object {
    Class  isa ;
};·

類對象的定義是這樣的:

typedef struct objc_class *Class;
struct objc_class {
  Class isa;
  Class super_class ;
  ...
}

可以看出,不管是實(shí)例對象還是類對象都有一個(gè) isa 成員變量,

  1. 實(shí)例對象中的 isa 指向類結(jié)構(gòu)稱作 class(普通的),class 結(jié)構(gòu)存儲類的普通成員變量與普通成員方法(-開頭的方法)
  2. 類對象中的 isa 指向類結(jié)構(gòu)被稱作 metaclass , metaclass 存儲類的類成員變量與類成員方法(+開頭的方法)

??注意??:OC語法里面,并不存在類成員變量這個(gè)概念。雖然 @property 中可以添加 class 描述,但是并不會生成類成員變量。

常用API

獲取變量信息

在JSON轉(zhuǎn)Model 中需要獲取對象的所有屬性:

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)前類的屬性列表,如果需要獲取父類的需要自行向上遍歷。

上面獲取到的只是對象的屬性列表,如果想要獲取對象的成員列表,

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);

獲取方法信息

除了獲取變量信息,還能會獲取到方法列表

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 的對象,如果換成下面的方式,獲取到的就是類方法列表

// 獲取到的是 metaclass
Class cls = object_getClass([self class]);
Method* methodList = class_copyMethodList(cls,&methodCount);

對于 [self class] & object_getClass(self) 的區(qū)別:

self 為實(shí)例對象 self 為類對象
[self class] 類對象(等價(jià)于object_getClass) 類對象(自身)
object_getClass(self) 類對象 元類
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容