runtime常用方法

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



最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容