你好,歡迎來到IOS教程網

 Ios教程網 >> IOS使用技巧 >> IOS技巧綜合 >> iOS Runtime筆記

iOS Runtime筆記

編輯:IOS技巧綜合
[摘要]本文是對iOS Runtime筆記的講解,對學習IOS蘋果軟件開發有所幫助,與大家分享。

Objective-C語言是一門動態語言,它將很多靜態語言在編譯和鏈接時期做的事放到了運行時來處理。這種動態語言的優勢在於:我們寫代碼時更具靈活性,如我們可以把消息轉發給我們想要的對象,或者隨意交換一個方法的實現等。

Objective-C類是由Class類型來表示的,它實際上是一個指向objc_class結構體的指針。它的定義如下:

typedef struct objc_class *Class;

查看objc/runtime.h中objc_class結構體的定義如下:

struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class super_class                       OBJC2_UNAVAILABLE;  // 父類
    const char *name                        OBJC2_UNAVAILABLE;  // 類名
    long version                            OBJC2_UNAVAILABLE;  // 類的版本信息,默認為0
    long info                               OBJC2_UNAVAILABLE;  // 類信息,供運行期使用的一些位標識
    long instance_size                      OBJC2_UNAVAILABLE;  // 該類的實例變量大小
    struct objc_ivar_list *ivars            OBJC2_UNAVAILABLE;  // 該類的成員變量鏈表
    struct objc_method_list **methodLists   OBJC2_UNAVAILABLE;  // 方法定義的鏈表
    struct objc_cache *cache                OBJC2_UNAVAILABLE;  // 方法緩存
    struct objc_protocol_list *protocols    OBJC2_UNAVAILABLE;  // 協議鏈表
#endif

} OBJC2_UNAVAILABLE;

1、

常用舉例

Class newClass = objc_allocateClassPair([NSError class], "TestClass", 0); // 創建新的類

參數1: 父類
參數2: 子類名
參數3: extraBytes
class_addMethod(newClass, @selector(testMetaClass), (IMP)TestMetaClass, "v@:"); // 為新的類添加方法
參數1: 類名
參數2: 方法名稱
參數3: 方法(IMP)你寫的方法名
參數4: 一個定義該函數返回值類型和參數類型的字符串 根據返回值和參數動態的確定 https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html 這裡可以查看對應返回值類型的表達方法 v表示void 後邊的:後邊表示參數 比如說 定義 int:(id self, SEL _cmd,NSString * name) 那麼就是 i@:@ 這樣的。

objc_registerClassPair(newClass); // 注冊創建的類 id instance = [[newClass alloc] initWithDomain:@"some domain" code:0 userInfo:nil]; // 實例化對象 [instance performSelector:@selector(testMetaClass)]; // 調用方法

// 獲取類的類名
const char * class_getName ( Class cls );


// 獲取類的父類
Class class_getSuperclass ( Class cls );

// 判斷給定的Class是否是一個元類
BOOL class_isMetaClass ( Class cls );

// 獲取實例大小

size_t class_getInstanceSize ( Class cls );


在objc_class中,所有的成員變量、屬性的信息是放在鏈表ivars中的。ivars是一個
// 獲取類中指定名稱實例成員變量的信息
Ivar class_getInstanceVariable ( Class cls, const char *name );

// 獲取類成員變量的信息
Ivar class_getClassVariable ( Class cls, const char *name );

// 添加成員變量
BOOL class_addIvar ( Class cls, const char *name, size_t size, uint8_t alignment, const char *types );

// 獲取整個成員變量列表
Ivar * class_copyIvarList ( Class cls, unsigned int *outCount );

class_copyIvarList函數,它返回一個指向成員變量信息的數組,數組中每個元素是指向該成員變量信息的objc_ivar結構體的指針。這個數組不包含在父類中聲明的變量。outCount指針返回數組的大小。需要注意的是,我們必須使用free()來釋放這個數組

// 獲取指定的屬性
objc_property_t class_getProperty ( Class cls, const char *name );

// 獲取屬性列表
objc_property_t * class_copyPropertyList ( Class cls, unsigned int *outCount );

// 為類添加屬性
BOOL class_addProperty ( Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount );

// 替換類的屬性
void class_replaceProperty ( Class cls, const char *name, const objc_property_attribute_t *attributes, unsigned int attributeCount );


// 添加方法
BOOL class_addMethod ( Class cls, SEL name, IMP imp, const char *types );

// 獲取實例方法
Method class_getInstanceMethod ( Class cls, SEL name );

// 獲取類方法
Method class_getClassMethod ( Class cls, SEL name );

// 獲取所有方法的數組
Method * class_copyMethodList ( Class cls, unsigned int *outCount );

// 替代方法的實現
IMP class_replaceMethod ( Class cls, SEL name, IMP imp, const char *types );

// 返回方法的具體實現
IMP class_getMethodImplementation ( Class cls, SEL name );
IMP class_getMethodImplementation_stret ( Class cls, SEL name );

// 類實例是否響應指定的selector
BOOL class_respondsToSelector ( Class cls, SEL sel );

class_addMethod的實現會覆蓋父類的方法實現,但不會取代本類中已存在的實現,如果本類中包含一個同名的實現,則函數會返回NO。如果要修改已存在實現,可以使用method_setImplementation。一個Objective-C方法是一個簡單的C函數,它至少包含兩個參數—self和_cmd。所以,我們的實現函數(IMP參數指向的函數)至少需要兩個參數,如下所示:

void myMethodIMP(id self, SEL _cmd)
{
    // implementation ....
}


// 添加協議
BOOL class_addProtocol ( Class cls, Protocol *protocol );

// 返回類是否實現指定的協議
BOOL class_conformsToProtocol ( Class cls, Protocol *protocol );

// 返回類實現的協議列表
Protocol * class_copyProtocolList ( Class cls, unsigned int *outCount );


// 獲取版本號
int class_getVersion ( Class cls );

// 設置版本號
void class_setVersion ( Class cls, int version );

// 創建一個新類和元類
Class objc_allocateClassPair ( Class superclass, const char *name, size_t extraBytes );

// 銷毀一個類及其相關聯的類
void objc_disposeClassPair ( Class cls );

// 在應用中注冊由objc_allocateClassPair創建的類
void objc_registerClassPair ( Class cls );

// 創建類實例
id class_createInstance ( Class cls, size_t extraBytes );

// 在指定位置創建類實例
id objc_constructInstance ( Class cls, void *bytes );

// 銷毀類實例
void * objc_destructInstance ( id obj );


// 返回指定對象的一份拷貝
id object_copy ( id obj, size_t size );

// 釋放指定對象占用的內存
id object_dispose ( id obj );

// 修改類實例的實例變量的值
Ivar object_setInstanceVariable ( id obj, const char *name, void *value );

// 獲取對象實例變量的值
Ivar object_getInstanceVariable ( id obj, const char *name, void **outValue );

// 返回指向給定對象分配的任何額外字節的指針
void * object_getIndexedIvars ( id obj );

// 返回對象中實例變量的值
id object_getIvar ( id obj, Ivar ivar );

// 設置對象中實例變量的值
void object_setIvar ( id obj, Ivar ivar, id value )


// 返回給定對象的類名
const char * object_getClassName ( id obj );

// 返回對象的類
Class object_getClass ( id obj );

// 設置對象的類
Class object_setClass ( id obj, Class cls );


// 獲取已注冊的類定義的列表
int objc_getClassList ( Class *buffer, int bufferCount );

// 創建並返回一個指向所有已注冊類的指針列表
Class * objc_copyClassList ( unsigned int *outCount );

// 返回指定類的類定義
Class objc_lookUpClass ( const char *name );
Class objc_getClass ( const char *name );
Class objc_getRequiredClass ( const char *name );

// 返回指定類的元類
Class objc_getMetaClass ( const char *name );
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved