數(shù)據(jù)類型
Class
oc類的原型
typedef struct objc_class* Class;
Method
方法的原型
typedef struct objc_method*Method;
struct objc_method {
SEL?method_name?????????????????OBJC2_UNAVAILABLE;//?方法名
char?*method_types??????????????????OBJC2_UNAVAILABLE;
IMP?method_imp??????????????????????OBJC2_UNAVAILABLE;//?方法實(shí)現(xiàn)
}
Ivar
實(shí)例變量的原型
typedef struct objc_ivar*Ivar;
Category
分類的原型
typedef struct objc_category*Category;
objc_property_t
OC中公開的屬性
typedef struct objc_property*objc_property_t;
IMP
指向方法執(zhí)行的起始點(diǎn)
id (*IMP)(id,SEL,...)
第一個(gè)參數(shù)指向self,第二個(gè)參數(shù)指向一個(gè)方法選擇器(_cmd)。
SEL
方法選擇器的原型。
typedef struct objc_selector*SEL;
在runtime中一個(gè)方法選擇器代表著一個(gè)方法。一個(gè)方法選擇器是一個(gè)被注冊在OCruntime中的C語言字符串。當(dāng)一個(gè)class被加載時(shí),方法選擇器會(huì)自動(dòng)編譯在runtime中。
你可以添加一個(gè)新的方法選擇器和尋找一個(gè)已經(jīng)存在的方法選擇器通過使用函數(shù) sel_registerName。
當(dāng)要使用方法選擇器的時(shí)候,你可以從函數(shù)sel_registerName或者OC編譯器指令@selector()獲得方法選擇器,你不能僅僅使用一個(gè)c字符串當(dāng)中SEL。
定義一個(gè)OC方法。
struct objc_method_description {SEL name; char* types;};
name: 這個(gè)方法在runtime中的名字。
types:方法參數(shù)的類型。(蘋果公司為了表明函數(shù)的形參,定義了自己的一種關(guān)于數(shù)據(jù)的類型)。
包含一系列方法定義的數(shù)組。
struct objc_method_list{struct?objc_method_list*obsolete; int method_count; struct objc_method method_list[1];}
obsolete:為將來保留。
method_count:在方法列表數(shù)組中方法的數(shù)量。
method_list:一系列方法的數(shù)據(jù)結(jié)構(gòu)。
為了最優(yōu)化方法調(diào)用。包含最近使用過方法的指針。
struct objc_cache{unsigned int mask;unsigned int occupied;?Method?buckets[1];};
mask:為了最優(yōu)化查找objc_cache內(nèi)的方法,mask通常和一個(gè)方法的方法選擇器進(jìn)行與操作。這跟一種哈希運(yùn)算法則很相似。mask表示buckets分配過的內(nèi)存的大小。(具體也不明白啥意思,等待自己學(xué)習(xí))。
occupied:已占用的buckets的大小。
buckets:一個(gè)指向存儲(chǔ)方法數(shù)據(jù)結(jié)構(gòu)的數(shù)組的指針。這個(gè)數(shù)組不大于mask + 1個(gè)項(xiàng)目。這個(gè)指針可能指向NULL,表明這個(gè)緩存數(shù)組沒有使用過,數(shù)組或許會(huì)隨著時(shí)間增長。
objc_protocol_list
協(xié)議的列表
struct objc_protocol_list{struct?objc_protocol_list*next;int count; Protocol*list[1];};
next:指向另一個(gè) objc_protocol_list 數(shù)據(jù)結(jié)構(gòu)。
count:這個(gè)列表協(xié)議的數(shù)量。
list:包含一系列協(xié)議的數(shù)組的指針。
objc_property_attribute_t
定義property的屬性。
typedef struct{const char*name;const char*value;} objc_property_attribute_t;
name:這個(gè)屬性的名字。
value:這個(gè)屬性的值。(通常為空)。
objc_object
類的對象。
struct objc_object{Class isa;};
isa:一個(gè)指向?qū)ο蟮闹羔槨?/p>
當(dāng)你創(chuàng)建一個(gè)類的對象的時(shí)候,這分配的空間中包含一個(gè)objc_object的數(shù)據(jù)結(jié)構(gòu),這個(gè)數(shù)據(jù)結(jié)構(gòu)包含這個(gè)對象的實(shí)例變量的數(shù)據(jù)。
這個(gè)alloc和allocWithZone:方法使用class_createInstance函數(shù)創(chuàng)建objc_object數(shù)據(jù)結(jié)構(gòu)。
objc_super
超類的對象
struct objc_super{id receiver;Class class;};
receiver:指向一個(gè)id類型,類的對象。
class: 指向一個(gè)Class數(shù)據(jù)結(jié)構(gòu),要發(fā)送消息的超類。
當(dāng)編譯器遇到super關(guān)鍵詞時(shí),編譯器會(huì)生成objc_super結(jié)構(gòu)體,這個(gè)結(jié)構(gòu)體表明的要接收信息的超類。
關(guān)聯(lián)屬性
使用一個(gè)特定的key可以對一個(gè)對象對關(guān)聯(lián)另一個(gè)對象。
void objc_setAssociatedObject(id object,void* key,id value,objc_AssociationPolicy?policy)
形參:
object: 要關(guān)聯(lián)的對象;
key:關(guān)聯(lián)對象的key,整個(gè)APP這個(gè)key應(yīng)該是唯一的。一個(gè)對象可能有許多關(guān)聯(lián)對象,所以需要一個(gè)key來對應(yīng)一個(gè)關(guān)聯(lián)的對象。
value:關(guān)聯(lián)的對象(包括一些基本類型數(shù)據(jù))。
policy:關(guān)聯(lián)對象的內(nèi)存管理政策,這些政策有如下:
enum{
OBJC_ASSOCIATION_ASSIGN=0,
OBJC_ASSOCIATION_RETAIN_NONATOMIC=1,
OBJC_ASSOCIATION_COPY_NONATOMIC=3,
OBJC_ASSOCIATION_RETAIN=01401,
OBJC_ASSOCIATION_COPY=01403};
不同的對象應(yīng)選擇正確的內(nèi)存管理政策,如基本數(shù)據(jù)類型通常用OBJC_ASSOCIATION_ASSIGN。
id objc_getAssociatedObject(id object,void* key)
void objc_removeAssociatedObjects(id object)
這兩個(gè)API可以參考上面API。
方法選擇器
const char* sel_getName(SEL aSelector)
獲取指定SEL的名稱
SEL sel_registerName(const char*str)
SEL sel_getUid(const char*str)
兩個(gè)方法類似,但sel_registerName還有注冊在runtime的功能,兩個(gè)都能從輸入的字符串中獲取到SEL。
BOOL sel_isEqual(SEL lhs,SEL rhs)
比較兩個(gè)SEL是否相等。
工作在Class
Method?class_getInstanceMethod(Class aClass,SEL aSelector)
獲取在aClass內(nèi)SEL為aSelector的對象方法的Method結(jié)構(gòu)體。如果這個(gè)類和父類都不存在這個(gè)方法,則返回NULL。
Method?class_getClassMethod(Class aClass,SEL aSelector)
獲取在aClass內(nèi)SEL為aSelector的類方法的Method結(jié)構(gòu)體。如果這個(gè)類和父類都不存在這個(gè)方法,則返回NULL。
BOOL class_addMethod(Class cls,SEL name,IMP imp,const char*types)
type:所要添加IMP的type encoding
將name和imp組成的Method添加到cls中,如果添加失敗(如已經(jīng)存在name的SEL),將返回NO,成功返回YES。
IMP class_replaceMethod(Class cls,SEL name,IMP imp,const char*types)
如果存在name構(gòu)成的Method,則使用method_setImplementation設(shè)置新的IMP,且返回舊的IMP,如果不存在name的Method,則執(zhí)行class_addMethod函數(shù)。
objc_property_t* class_copyPropertyList(Class cls, unsigned int*outCount)
返回cls里的Property列表的數(shù)組,outCount代表這個(gè)數(shù)組的數(shù)量。父類的Property不包括這個(gè)數(shù)組內(nèi)。最后必須使用free()釋放這個(gè)數(shù)組的內(nèi)存。
工作在Method
IMP method_getImplementation(Method?method)
獲取指定method的IMP。
IMP method_setImplementation(Method?method,IMP imp)
設(shè)置新的IMP,且返回舊的IMP
const char*method_getTypeEncoding(Method?method)
獲取指定method的參數(shù)type encoding
char* method_copyReturnType(Method?method)
獲取指定method的返回值type encoding,使用完后,必須使用free()釋放返回的c字符串。
void method_exchangeImplementations(Method?m1,Method?m2)
交換m1和m2的IMP 內(nèi)部執(zhí)行的是:
IMP imp1=method_getImplementation(m1);
IMP imp2=method_getImplementation(m2);
method_setImplementation(m1,imp2);
method_setImplementation(m2,imp1);
工作在Properties
const char*property_getName(objc_property_t property)
獲取指定Property的名字,用c字符串。