• 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指针)

  • 相关阅读:
    使用fiddler2抓取手机发出的请求信息
    HTML转义字符集合
    spm3安装和使用
    JSP
    Servlet
    Struts2
    java多线程-消费者和生产者模式
    java异常处理机制(try-catch-finally)
    java内部类
    java上转型和下转型(对象的多态性)
  • 原文地址:https://www.cnblogs.com/sunyaxue/p/9739981.html
Copyright © 2020-2023  润新知