類(lèi)
類(lèi)結(jié)構(gòu)
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE; // 父類(lèi)
const char *name OBJC2_UNAVAILABLE; // 類(lèi)名
long version OBJC2_UNAVAILABLE; // 類(lèi)的版本信息,默認(rèn)為0
long info OBJC2_UNAVAILABLE; // 類(lèi)信息,供運(yùn)行期使用的一些位標(biāo)識(shí)
long instance_size OBJC2_UNAVAILABLE; // 該類(lèi)的實(shí)例變量大小
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; // 該類(lèi)的成員變量鏈表
struct objc_method_list **methodLists OBJC2_UNAVAILABLE; // 方法定義的鏈表
struct objc_cache *cache OBJC2_UNAVAILABLE; // 方法緩存
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; // 協(xié)議鏈表
#endif
} OBJC2_UNAVAILABLE;
struct objc_object {
Class isa OBJC_ISA_AVAILABILITY;
};
類(lèi)實(shí)例結(jié)構(gòu)
typedef struct objc_object *id;
常用函數(shù)
// 獲取類(lèi)的類(lèi)名
const char * class_getName ( Class cls );
// 獲取類(lèi)的父類(lèi)
Class class_getSuperclass ( Class cls );
// 判斷給定的Class是否是一個(gè)元類(lèi)
BOOL class_isMetaClass ( Class cls );
// 獲取實(shí)例大小
size_t class_getInstanceSize ( Class cls );
// 獲取類(lèi)中指定名稱(chēng)實(shí)例成員變量的信息
Ivar class_getInstanceVariable ( Class cls, const char *name );
// 獲取類(lèi)成員變量的信息
Ivar class_getClassVariable ( Class cls, const char *name );
// 添加成員變量,方法只能在objc_allocateClassPair函數(shù)與objc_registerClassPair之間調(diào)用
BOOL class_addIvar ( Class cls, const char *name, size_t size, uint8_t alignment, const char *types );
// 獲取整個(gè)成員變量列表 ,后續(xù)必須使用free釋放Ivar這個(gè)數(shù)組對(duì)象
Ivar * class_copyIvarList ( Class cls, unsigned int *outCount );
// 獲取指定的屬性
objc_property_t class_getProperty ( Class cls, const char *name );
// 獲取屬性列表
objc_property_t * class_copyPropertyList ( Class cls, unsigned int *outCount );
// 為類(lèi)添加屬性
BOOL class_addProperty ( Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount );
// 替換類(lèi)的屬性
void class_replaceProperty ( Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount );
方法
結(jié)構(gòu)
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)
}
類(lèi)方法的常用函數(shù)
// 添加方法
BOOL class_addMethod ( Class cls, SEL name, IMP imp, const char *types );
// 獲取實(shí)例方法
Method class_getInstanceMethod ( Class cls, SEL name );
// 獲取類(lèi)方法
Method class_getClassMethod ( Class cls, SEL name );
// 獲取所有方法的數(shù)組
Method * class_copyMethodList ( Class cls, unsigned int *outCount );
// 替代方法的實(shí)現(xiàn)
IMP class_replaceMethod ( Class cls, SEL name, IMP imp, const char *types );
// 返回方法的具體實(shí)現(xiàn)
IMP class_getMethodImplementation ( Class cls, SEL name );
IMP class_getMethodImplementation_stret ( Class cls, SEL name );
// 類(lèi)實(shí)例是否響應(yīng)指定的selector
BOOL class_respondsToSelector ( Class cls, SEL sel );
方法的常用函數(shù)
// 調(diào)用指定方法的實(shí)現(xiàn)
id method_invoke ( id receiver, Method m, ... );
// 調(diào)用返回一個(gè)數(shù)據(jù)結(jié)構(gòu)的方法的實(shí)現(xiàn)
void method_invoke_stret ( id receiver, Method m, ... );
// 獲取方法名
SEL method_getName ( Method m );
// 返回方法的實(shí)現(xiàn)
IMP method_getImplementation ( Method m );
// 獲取描述方法參數(shù)和返回值類(lèi)型的字符串
const char * method_getTypeEncoding ( Method m );
// 獲取方法的返回值類(lèi)型的字符串
char * method_copyReturnType ( Method m );
// 獲取方法的指定位置參數(shù)的類(lèi)型字符串
char * method_copyArgumentType ( Method m, unsigned int index );
// 通過(guò)引用返回方法的返回值類(lèi)型字符串
void method_getReturnType ( Method m, char *dst, size_t dst_len );
// 返回方法的參數(shù)的個(gè)數(shù)
unsigned int method_getNumberOfArguments ( Method m );
// 通過(guò)引用返回方法指定位置參數(shù)的類(lèi)型字符串
void method_getArgumentType ( Method m, unsigned int index, char *dst, size_t dst_len );
// 返回指定方法的方法描述結(jié)構(gòu)體
struct objc_method_description * method_getDescription ( Method m );
// 設(shè)置方法的實(shí)現(xiàn)
IMP method_setImplementation ( Method m, IMP imp );
// 交換兩個(gè)方法的實(shí)現(xiàn)
void method_exchangeImplementations ( Method m1, Method m2 )
//函數(shù)調(diào)用
objc_msgSend(receiver, selector)
objc_msgSend(receiver, selector, arg1, arg2, ...)
方法選擇器
// 返回給定選擇器指定的方法的名稱(chēng)
const char * sel_getName ( SEL sel );
// 在Objective-C Runtime系統(tǒng)中注冊(cè)一個(gè)方法,將方法名映射到一個(gè)選擇器,并返回這個(gè)選擇器
SEL sel_registerName ( const char *str );
// 在Objective-C Runtime系統(tǒng)中注冊(cè)一個(gè)方法
SEL sel_getUid ( const char *str );
// 比較兩個(gè)選擇器
BOOL sel_isEqual ( SEL lhs, SEL rhs );
動(dòng)態(tài)創(chuàng)建類(lèi)
// 創(chuàng)建一個(gè)新類(lèi)和元類(lèi) extraBytes通常指定為0,該參數(shù)是分配給類(lèi)和元類(lèi)對(duì)象尾部的索引ivars的字節(jié)數(shù)。
Class objc_allocateClassPair ( Class superclass, const char *name, size_t extraBytes );
// 銷(xiāo)毀一個(gè)類(lèi)及其相關(guān)聯(lián)的類(lèi)
void objc_disposeClassPair ( Class cls );
// 在應(yīng)用中注冊(cè)由objc_allocateClassPair創(chuàng)建的類(lèi)
void objc_registerClassPair ( Class cls );
示例:
Class cls = objc_allocateClassPair(MyClass.class, "MySubClass", 0);
class_addMethod(cls, @selector(submethod1), (IMP)imp_submethod1, "v@:");
class_replaceMethod(cls, @selector(method1), (IMP)imp_submethod1, "v@:");
class_addIvar(cls, "_ivar1", sizeof(NSString *), log(sizeof(NSString *)), "i");
objc_property_attribute_t type = {"T", "@\"NSString\""};
objc_property_attribute_t ownership = { "C", "" };
objc_property_attribute_t backingivar = { "V", "_ivar1"};
objc_property_attribute_t attrs[] = {type, ownership, backingivar};
class_addProperty(cls, "property2", attrs, 3);
objc_registerClassPair(cls);
id instance = [[cls alloc] init];
[instance performSelector:@selector(submethod1)];
[instance performSelector:@selector(method1)];
動(dòng)態(tài)創(chuàng)建對(duì)象
// 創(chuàng)建類(lèi)實(shí)例
id class_createInstance ( Class cls, size_t extraBytes );
// 在指定位置創(chuàng)建類(lèi)實(shí)例
id objc_constructInstance ( Class cls, void *bytes );
// 銷(xiāo)毀類(lèi)實(shí)例
void * objc_destructInstance ( id obj );
例子:
id theObject = class_createInstance(NSString.class, sizeof(unsigned));
id str1 = [theObject init];
NSLog(@"%@", [str1 class]);
id str2 = [[NSString alloc] initWithString:@"test"];
NSLog(@"%@", [str2 class]);
成員變量、屬性
Ivar 結(jié)構(gòu)
Ivar是表示實(shí)例變量的類(lèi)型,其實(shí)際是一個(gè)指向objc_ivar結(jié)構(gòu)體的指針,其定義如下:
typedef struct objc_ivar *Ivar;
struct objc_ivar {
char *ivar_name OBJC2_UNAVAILABLE; // 變量名
char *ivar_type OBJC2_UNAVAILABLE; // 變量類(lèi)型
int ivar_offset OBJC2_UNAVAILABLE; // 基地址偏移字節(jié)
#ifdef __LP64__
int space OBJC2_UNAVAILABLE;
#endif
}
objc_property_t 屬性結(jié)構(gòu)
typedef struct objc_property *objc_property_t;
typedef struct {
const char *name; // 特性名
const char *value; // 特性值
} objc_property_attribute_t;
常用方法
// 獲取成員變量名
const char * ivar_getName ( Ivar v );
// 獲取成員變量類(lèi)型編碼
const char * ivar_getTypeEncoding ( Ivar v );
// 獲取成員變量的偏移量
ptrdiff_t ivar_getOffset ( Ivar v );
// 設(shè)置關(guān)聯(lián)對(duì)象
void objc_setAssociatedObject ( id object, const void *key, id value, objc_AssociationPolicy policy );
// 獲取關(guān)聯(lián)對(duì)象
id objc_getAssociatedObject ( id object, const void *key );
// 移除關(guān)聯(lián)對(duì)象
void objc_removeAssociatedObjects ( id object );
// 獲取屬性名
const char * property_getName ( objc_property_t property );
// 獲取屬性特性描述字符串
const char * property_getAttributes ( objc_property_t property );
// 獲取屬性中指定的特性
char * property_copyAttributeValue ( objc_property_t property, const char *attributeName );
// 獲取屬性的特性列表
objc_property_attribute_t * property_copyAttributeList ( objc_property_t property, unsigned int *outCount );