iOS Runtime筆記,iosruntime筆記

來源:互聯網
上載者:User

iOS Runtime筆記,iosruntime筆記

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 );// 類執行個體是否響應指定的selectorBOOL 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 );
 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.