iOS底层结构

一、Class

typedef struct objc_class *Class;

struct objc_class {

    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;

 

#if !__OBJC2__

    Class _Nullable super_class                              OBJC2_UNAVAILABLE;/*父类*/ 

    const char * _Nonnull name                               OBJC2_UNAVAILABLE;/*类名称*/  

    long version                                             OBJC2_UNAVAILABLE;/*版本信息*/  

    long info                                                OBJC2_UNAVAILABLE;/*类信息*/ 

    long instance_size                                       OBJC2_UNAVAILABLE;/*实例大小*/  

    struct objc_ivar_list * _Nullable ivars                  OBJC2_UNAVAILABLE;/*实例参数链表*/  

    struct objc_method_list * _Nullable * _Nullable methodLists                    OBJC2_UNAVAILABLE;/*类方法链表*/  

    struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE;/*类方法缓存*/ 

    struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE;/*协议链表*/  

#endif

 

} OBJC2_UNAVAILABLE;

二、Object

struct objc_object {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};

三、Method

typedef struct objc_method *Method;  
struct objc_method {  
     SEL method_name                                          OBJC2_UNAVAILABLE;/*标示方法名称*/  
     char *method_types                                       OBJC2_UNAVAILABLE;/*方法的参数类型*/  
     IMP method_imp                                           OBJC2_UNAVAILABLE;/*指向该方法的具体实现的函数指针*/  
 }  
       
struct objc_method_list {  
     struct objc_method_list *obsolete                        OBJC2_UNAVAILABLE;  
   
     int method_count                                         OBJC2_UNAVAILABLE;  
 #ifdef __LP64__  
     int space                                                OBJC2_UNAVAILABLE;  
 #endif  
     /* variable length structure */  
     struct objc_method method_list[1]                        OBJC2_UNAVAILABLE;  
 }  

IMP

#if !OBJC_OLD_DISPATCH_PROTOTYPES
typedef void (*IMP)(void /* id, SEL, ... */ ); 
#else
typedef id (*IMP)(id, SEL, ...); 
#endif

SEL

typedef struct objc_selector *SEL;

四、Ivar

typedef struct ivar_t *Ivar;

struct ivar_t {
#if __x86_64__
    // *offset was originally 64-bit on some x86_64 platforms.
    // We read and write only 32 bits of it.
    // Some metadata provides all 64 bits. This is harmless for unsigned 
    // little-endian values.
    // Some code uses all 64 bits. class_addIvar() over-allocates the 
    // offset for their benefit.
#endif
    int32_t *offset;
    const char *name;
    const char *type;
    // alignment is sometimes -1; use alignment() instead
    uint32_t alignment_raw;
    uint32_t size;

    uint32_t alignment() const {
        if (alignment_raw == ~(uint32_t)0) return 1U << WORD_SHIFT;
        return 1 << alignment_raw;
    }
};

五、objc_property_t

typedef struct property_t *objc_property_t;

struct property_t {
    const char *name;
    const char *attributes;
};

 

测试

@interface ViewController (){
    int index;
    NSString *name;
}
@property (nonatomic,strong) UILabel *label;

@end

获取ivarList

 unsigned int count;
 Ivar *ivarList = class_copyIvarList([self class], &count);
 for (int i = 0; i < count; i++) {
     NSString *name = [NSString stringWithUTF8String:ivar_getName(ivarList[i])];
     NSString *type = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivarList[i])];
     long int offset = ivar_getOffset(ivarList[i]);
     NSLog(@"***IvarName:%@-----type:%@----offset:%ld", name, type, offset);
 }
 free(ivarList);
2018-10-03 15:48:27.742887+0800 TPNotification[3325:2368470] ***IvarName:index-----type:i----offset:848
2018-10-03 15:48:27.743003+0800 TPNotification[3325:2368470] ***IvarName:name-----type:@"NSString"----offset:856
2018-10-03 15:48:27.743109+0800 TPNotification[3325:2368470] ***IvarName:_label-----type:@"UILabel"----offset:864

获取propertyList

unsigned int count;
objc_property_t *properties = class_copyPropertyList([self class], &count);
for (int i =0; i < count; i++) {
   const char *name =property_getName(properties[i]);
   const char *attributes = property_getAttributes(properties[i]);
   NSLog(@"***propertyName:%@------attributes:%@", [NSString stringWithCString:name encoding:NSUTF8StringEncoding], [NSString stringWithCString:attributes encoding:NSUTF8StringEncoding]);
} free(properties);
2018-10-03 15:52:31.608676+0800 TPNotification[3420:2371592] ***propertyName:label------attributes:T@"UILabel",&,N,V_label

获取对象方法列表

  unsigned int count;
  Method *methods =
  class_copyMethodList([self class], &count);
  for(int i =0; i < count; i++) {
     SEL name = method_getName(methods[i]);
     IMP imp = method_getImplementation(methods[i]);
     const char *type = method_getTypeEncoding(methods[i]);
     NSLog(@"***实例方法name:%@----IMP:%p------types:%@",NSStringFromSelector(name), imp, [NSString stringWithCString:type encoding:NSUTF8StringEncoding]);
   }
   free(methods);
2018-10-03 16:00:44.381683+0800 TPNotification[3640:2378121] ***实例方法name:viewDidLayoutSubviews----IMP:0x104b623c0------types:v16@0:8
2018-10-03 16:00:44.381764+0800 TPNotification[3640:2378121] ***实例方法name:viewDidLoad----IMP:0x104b61ee0------types:v16@0:8

获取类方法列表

unsigned int count;
Method *methods =class_copyMethodList(object_getClass([self class]),
                                              &count);
for (int i =0; i < count; i++) {
     SEL name = method_getName(methods[i]);
     IMP imp = method_getImplementation(methods[i]);
     const char *type = method_getTypeEncoding(methods[i]);
     NSLog(@"***类方法name:%@----IMP:%p------types:%@",NSStringFromSelector(name), imp, [NSString stringWithCString:type encoding:NSUTF8StringEncoding]);
 }
 free(methods);
2018-10-03 16:03:37.337046+0800 TPNotification[3715:2380344] ***类方法name:classMethod----IMP:0x108113470------types:v16@0:8

另一种获取类方法列表的方法

unsigned int count;
const char * class_name = class_getName([self class]);
Class metaClass = objc_getMetaClass(class_name);
Method *methods =class_copyMethodList(metaClass, &count);
for (int i =0; i < count; i++) {
    SEL name = method_getName(methods[i]);
    IMP imp = method_getImplementation(methods[i]);
    const char *type = method_getTypeEncoding(methods[i]);
    NSLog(@"***类方法name:%@----IMP:%p------types:%@",NSStringFromSelector(name), imp, [NSString stringWithCString:type encoding:NSUTF8StringEncoding]);
}
free(methods);

附上一张isa指针图(虚线isa指针,实线superclass指针)

 

posted on 2019-01-16 19:02  sunyaxue  阅读(226)  评论(0编辑  收藏  举报

导航