iOS開発-下層編-Class詳細

16389 ワード

前言:iOSの開発言語objective-cは、本当のオブジェクト向け言語ではなく、抽象的に理解しているだけです.実はそれはC+で、それをよく解釈できる公式があります.
OC = C + Runtime; 次にRuntimeの下にあるobjc-classについてよくお話しします.資料を準備し、objc 4-646/runtime.
一:Class定義
1.1 objc-apiについて少し説明します.hの中のOBJC_ISA_AVAILABILITY:
/*ご紹介します_attribute__((deprecated))の役割、_attributeは関数、変数、クラスに属性の説明をするキーワードであり、deprecatedは元の互換性を捨てる
もし_OBJC2__,元のクラス、コンパイラから警告*/
#if !defined(OBJC_ISA_AVAILABILITY)

#   if __OBJC2__

#       define OBJC_ISA_AVAILABILITY  __attribute__((deprecated))

#   else

#       define OBJC_ISA_AVAILABILITY  /* still available */

#   endif

#endif

 
 
typedef struct objc_method *Method;

typedef struct objc_ivar *Ivar;

typedef struct objc_category *Category;

typedef struct objc_property *objc_property_t;

 
 
1.2次はruntime.hのClassの定義:
struct objc_class {

    Class isa  OBJC_ISA_AVAILABILITY;//  Class    isa  

    

#if !__OBJC2__

    Class super_class                                        OBJC2_UNAVAILABLE;//  

    const char *name                                         OBJC2_UNAVAILABLE;//  

    long version                                             OBJC2_UNAVAILABLE;//   

    long info                                                OBJC2_UNAVAILABLE;//!*!            。 :CLS_CLASS (0x1L)       class; CLS_META(0x2L)     metaclass (runtime.h      )

    long instance_size                                       OBJC2_UNAVAILABLE;//    

    struct objc_ivar_list *ivars                             OBJC2_UNAVAILABLE;//             

    struct objc_method_list **methodLists                    OBJC2_UNAVAILABLE;//!*!  info           ,         

    struct objc_cache *cache                                 OBJC2_UNAVAILABLE;//  

    struct objc_protocol_list *protocols                     OBJC2_UNAVAILABLE;//  

#endif

    

} OBJC2_UNAVAILABLE;

 
 
 
 
二:class初期化
Runtimeの行動の一つがinitializeです.プログラムの実行中に、プログラム内のクラスごとにinitializeが呼び出されます.この呼び出しの時間は、クラスがメッセージを受信する前に発生しますが、そのスーパークラスがinitializeを受信した後に発生します.
//      Runtime   objc-initialize.m  ,    

typedef struct _objc_initializing_classes {

    int classesAllocated;//       

    Class *metaclasses;//    ,           

} _objc_initializing_classes;//       _objc_initializing_classes



//

static _objc_initializing_classes *_fetchInitializingClassList(BOOL create)

{

    _objc_pthread_data *data;

    //list    

    _objc_initializing_classes *list;

    Class *classes;

    

    data = _objc_fetch_pthread_data(create);

    if (data == nil) return nil;

    

    //       

    list = data->initializingClasses;

    if (list == nil) {

        if (!create) {

            return nil;

        } else {

            list = (_objc_initializing_classes *)

            _calloc_internal(1, sizeof(_objc_initializing_classes));

            data->initializingClasses = list;

        }

    }

    //    classes  metaclasses 

    classes = list->metaclasses;

    if (classes == nil) {

        // If _objc_initializing_classes exists, allocate metaclass array,

        // even if create == NO.

        // Allow 4 simultaneous class inits on this thread before realloc.

        list->classesAllocated = 4;

        classes = (Class *)

        _calloc_internal(list->classesAllocated, sizeof(Class));

        list->metaclasses = classes;

    }

    return list;

}

 
 
三.runtimeの下でClassの各操作(重要ないくつか)
    
3.1 add*(  )

        3.1.1 static IMP addMethod(Class cls, SEL name, IMP imp, const char *types, BOOL replace);//    

        3.1.2 BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types);//     

        3.1.3 BOOL class_addIvar(Class cls, const char *name, size_t size,uint8_t alignment, const char *type);//      

        3.1.4 static BOOL _class_addProperty(Class cls, const char *name,const objc_property_attribute_t *attrs, unsigned int count,BOOL replace);//    

    3.2 replace*(  )

        3.2.1 IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types); //    

        3.2.2 void class_replaceProperty(Class cls, const char *name,const objc_property_attribute_t *attrs, unsigned int n);//    

    3.3 get*(  )

        3.3.1 static Class getClass(const char *name);//   

        3.3.2 static ivar_t *getIvar(Class cls, const char *name);//     (static   “+“)

        3.3.3 Method class_getInstanceMethod(Class cls, SEL sel);//      

        3.3.4 static Method _class_getMethod(Class cls, SEL sel);;//     

        3.3.5 static Protocol *getProtocol(const char *name);//    

    3.4 set*(  )

        3.4.1 objc_class::setInitialized();//set initialized   

        3.4.2 static Class setSuperclass(Class cls, Class newSuper);//    

    3.5         void *objc_destructInstance(id obj);//        

 
 
四.Classの重要な関数
   
4.1 get*(  )

        4.1.1 object_getClass(id obj);

        4.1.2 IMP object_getMethodImplementation(id obj, SEL name);//        

        4.1.3 Ivar object_getInstanceVariable(id obj, const char *name, void **value)//      

    4.2 set*(  )

        4.2.1 Class object_setClass(id obj, Class cls);

        4.2.2 Ivar object_setInstanceVariable(id obj, const char *name, void *value);//      

        4.2.3 void object_setIvar(id obj, Ivar ivar, id value);//      

    4.3   

        4.3.1 static void _class_resolveClassMethod(Class cls, SEL sel, id inst);//

        4.3.2 static void _class_resolveInstanceMethod(Class cls, SEL sel, id inst);//

        4.3.3 unsigned _class_createInstancesFromZone(Class cls, size_t extraBytes, void *zone,id *results, unsigned num_requested);//        

    4.4     

        4.4.1 void    instrumentObjcMessageSends(BOOL flag);//flag  YES,               /tmp/msgSend-xxxx    。